# Technical Documentation: apache/groovy

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/apache/groovy)

### Src Spec Doc  Core Async Channels (`src/spec/doc/_core-async-channels.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

[[async-channels]]
== Channels

Channels provide Go-style inter-task communication. A producer sends values
into a channel; a consumer receives them as they arrive. The channel handles
synchronization and optional buffering — no shared mutable state needed:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=channel,indent=0]
----

Channels support unbuffered (rendezvous, `create()`) and buffered (`create(n)`)
modes. Sending blocks when the buffer is full; receiving blocks when empty.
With virtual threads, this blocking is essentially free.

Since channels implement `Iterable`, they also work with regular `for` loops
and Groovy collection methods.

[[async-channel-composition]]
== Channel Composition

`AsyncChannel` supports composable pipeline operations. Each
composition method returns a new channel connected to the source
by a background task.

=== filter

[source,groovy]
----
def source = AsyncChannel.create(10)
def evens = source.filter { it % 2 == 0 }

async {
    (1..10).each { source.send(it) }
    source.close()
}

for await (val in evens) { println val }  // 2, 4, 6, 8, 10
----

=== map

[source,groovy]
----
def doubled = source.map { it * 2 }
----

=== Chaining

Operations compose naturally:

[source,groovy]
----
def pipeline = source
    .filter { it > 50 }
    .map { it * 2 }

for await (val in pipeline) { process(val) }
----

=== merge

Combines two channels into one, interleaving values as they arrive:

[source,groovy]
----
def merged = channelA.merge(channelB)
for await (event in merged) { handle(event) }
----

=== split

Partitions a channel into two based on a predicate:

[source,groovy]
----
def (highPriority, normal) = orders.split { it.priority > 5 }
----

=== tap

Sends a copy of each value to a monitoring channel while passing
through unchanged:

[source,groovy]
----
def monitor = AsyncChannel.create(100)
def output = source.tap(monitor)
// output gets all values; monitor gets copies for logging
----

[[async-channel-select]]
== Channel Select

`ChannelSelect` waits for the first available value from multiple
channels — like Go's `select` statement:

[source,groovy]
----
import groovy.concurrent.ChannelSelect

def prices = AsyncChannel.create(10)
def alerts = AsyncChannel.create(10)

def sel = ChannelSelect.from(prices, alerts)
def result = await sel.select()
println "Channel ${result.index}: ${result.value}"
----

A select takes exactly one value from exactly one channel; the other
channels are left untouched. When several channels already have a value
waiting, the one listed first is taken. If every channel is closed and
drained, `select()` fails with `ChannelClosedException`.

That priority by list order means a channel that always has a value
waiting starves the channels listed after it. `fair()` returns a select
that rotates instead — each call starts at the channel after the one
that last won, like JCSP's `fairSelect` — so keep the instance across
calls:

[source,groovy]
----
def sel = ChannelSelect.from(requests, control).fair()
while (true) {
    def result = await sel.select()
    // control is served even while requests never runs dry
}
----

`random()` chooses uniformly at random among the ready channels instead,
as Go's `select` does. It keeps no state between calls, so it is equally
fair from any number of threads, but it gives no bound on how long a
ready channel may be passed over; `fair()` guarantees every ready channel
is taken within _n_ calls.

=== Mixed offers

A select may also _offer to send_ — the mixed choice of the CSP
literature: "I will send my opener, or take my peer's if it sends
first". Offers are built with the static factories `send` and `receive`
and combined with `offers`, mirroring the send cases of Go's `select`:

[source,groovy]
----
import static groovy.concurrent.ChannelSelect.*

def result = await offers(send(ping, 1), receive(pong)).select()
if (result.send) {
    // my opener committed: continue the ping branch
} else {
    // my peer opened first: result.value is the pong opener
}
----

Exactly one offer commits; a committed send behaves exactly like
`ping.send(1)`, while a retired one leaves no trace — no buffered
residue, no waiting sender — just as a losing receive leaves its channel
untouched. `fair()` and `random()` order the scan over offers exactly as
they do over channels, and send offers require channels created by
`AsyncChannel.create`.

A send offer commits as soon as its channel can accept the value: when a
receiver is waiting, or when buffer space holds it. Two peers racing a
mixed choice against each other therefore agree on a single opener only
over rendezvous (capacity-0) channels, where a send cannot complete
unilaterally; over buffered channels with space, each peer's send offer
commits at once under its own select and the peers proceed down
different branches of the same conversation.

=== Preconditions

Each branch may also carry a _precondition_ — the guarded choice of CSP.
`when` writes the guard onto the offer itself, as occam, Ada, Erlang and
Kotlin do:

[source,groovy]
----
def sel = offers(receive(input).when { held.size() < capacity },   // <1>
                 receive(request).when { !held.isEmpty() })        // <2>
while (true) {
    def result = await sel.select()
    if (result.index == 0) {
        held.addLast(result.value)
    } else {
        await reply.send(held.removeFirst())
    }
}
----
<1> take input only while there is room
<2> answer a request only while there is something to hand over

A guarded-off offer is not registered on its channel, so nothing is taken
from it and nothing is sent to it, but it keeps its position, so
`result.index` denotes the same branch either way. Dropping an offer from
the argument list instead would renumber every branch after it, silently
changing what an index denotes.

The guard is a closure rather than a boolean because it is consulted
afresh on every `select` call — that is what lets one select be built
once and reused as the state it guards on changes. `when` returns a
guarded copy, leaving the original offer alone, and guards conjoin: over
a second `when`, both must hold.

`select` also accepts the same preconditions positionally, one flag per
offer, which suits a mask computed as a whole:

[source,groovy]
----
def result = await sel.select(held.size() < capacity, !held.isEmpty())
----

A flag is conjoined with whatever guard its offer carries — both must
hold for the offer to be registered — and passing a number of flags other
than the number of offers is an `IllegalArgumentException`. Enabling no
branch at all is a deadlock rather than a wait, so `select` fails with
`IllegalStateException`.

A branch can also be recognised by identity instead of by position:
`result.channel` is the channel the winning offer transferred over.

=== Timeouts

A deadline can be a branch of the select, as it is in Go, Rust, Clojure
and Kotlin, instead of an exception thrown around the whole select by
`orTimeout`. There are two forms, one for a timeout that re-arms on every
round and one for a fixed deadline.

The _timer offer_ `after` arms a fresh timer each time `select` is called
and commits, with the `Instant` it fired, if no channel offer could
commit first. It is the "wait for work, but not forever" branch of a
select that is built once and reused, and because the timer lives inside
the call, the held instance keeps its `fair()` rotation from round to
round:

[source,groovy]
----
import static groovy.concurrent.ChannelSelect.*

def sel = offers(receive(work), after(100)).fair()
while (true) {
    def result = await sel.select()
    if (result.timeout) {
        // nothing arrived within 100 ms of this call: result.value is the Instant
    } else {
        handle(result.value)
    }
}
----

A timer offer that loses its round is cancelled with the other losing
branches, so it leaves nothing armed. It reports `result.timeout` rather
than a channel: `result.channel` is `null` for a timeout, and `result.index`
still names the branch. So a select that carries a timer offer and
dispatches on `result.channel` must test `result.timeout` first, as the
loop above does. Like any offer it can be guarded with `when`, and
a guarded-off timer offer arms nothing. Several timer offers give
per-branch deadlines.

A timer offer with a positive delay is never ready at the moment the
select registers its offers, so the choice policy considers only the
channel offers that are ready at once; the timer commits only when none
was. A delay that is not positive has already elapsed, so that offer is
ready at registration and the policy treats it like any other ready
branch: priority takes whichever is listed first, and `fair()` rotates
over it. Listed last, `after(0)` is the `default` clause of Go's
`select` — take a transfer if one can complete at once, otherwise
proceed without waiting:

[source,groovy]
----
def result = await offers(receive(work), after(0)).select()
if (result.timeout) {
    // nothing was ready; do something else and come back
}
----

The _timer channel_ `AsyncChannel.after` is the fixed-deadline form: a
capacity-1 channel that delivers one value, the `Instant` it fired, once
the given delay has elapsed from its creation, and then closes, as Go's
`time.After` does. Received from within a select, it is a deadline shared
by every round that selects on it:

[source,groovy]
----
def deadline = AsyncChannel.after(5000)
def sel = ChannelSelect.from(work, deadline)
while (true) {
    def result = await sel.select()
    if (result.index == 1) break    // five seconds since the deadline was set
    handle(result.value)
}
----

Because it is an ordinary channel, a timer channel composes with
everything a channel does: it can be guarded with `when`, and once fired
`fair()` and `random()` treat it like any other ready channel. A timer
channel that loses a select keeps its value: it fires all the same and
holds the instant until received. Once that value has been taken, further
receives fail with `ChannelClosedException` rather than waiting forever,
and `isClosed()` reports that the timer has fired. Closing a timer channel
before it fires cancels it.

Both forms accept a `java.time.Duration` in place of milliseconds, and in
both a delay that is not positive has already elapsed: the timer channel
is created already holding its instant, and the timer offer is ready at
registration. That suits a deadline computed from an absolute time that
has already passed.

[[async-broadcast-channel]]
== BroadcastChannel

A `BroadcastChannel` delivers every value to all subscribers
(one-to-many), unlike `AsyncChannel` which is point-to-point:

[source,groovy]
----
import groovy.concurrent.BroadcastChannel

def broadcast = BroadcastChannel.create()
def sub1 = broadcast.subscribe()
def sub2 = broadcast.subscribe()

async {
    broadcast.send('hello')
    broadcast.send('world')
    broadcast.close()
}

// Both subscribers receive both messages
for await (msg in sub1) { println "Sub1: $msg" }
for await (msg in sub2) { println "Sub2: $msg" }
----

Late subscribers only receive messages sent after they subscribe.

=== Flow.Publisher interop

A `BroadcastChannel` can also be exposed as a `java.util.concurrent.Flow.Publisher`
via `asPublisher()`. Each call to `subscribe(Flow.Subscriber)` on the returned
publisher creates a new per-subscriber `AsyncChannel` under the hood and respects
standard Reactive Streams demand (`request(n)`):

[source,groovy]
----
def broadcast = BroadcastChannel.create()
def publisher = broadcast.asPublisher()

// Compose with any Reactive Streams operator, or consume with `for await`:
for await (msg in publisher) {
    println "Got: $msg"
}
----

[WARNING]
====
*Backpressure policy.* The publisher bridge uses _lossless, sender-gated_
backpressure: `send()` awaits delivery to every live subscriber, and each
per-subscriber channel has a bounded buffer (default 16). A subscriber that
never calls `request(n)` — or requests slowly — will fill its buffer, after
which `broadcast.send(...)` stalls for *all* subscribers until that
subscriber catches up. In other words, the slowest subscriber controls
producer throughput.

This matches the point-to-point semantics of `subscribe()` (values are
neither dropped nor reordered). If you need decoupled per-subscriber
policies (drop-newest, drop-oldest, latest-only, or unbounded buffering),
wrap the publisher with a Reactive Streams operator of your choice, or use
a subscriber that drains promptly with `request(Long.MAX_VALUE)`.
====

[NOTE]
====
*Terminal signals.* Per Reactive Streams §1.7, terminal completion is
not gated by demand: once the underlying `BroadcastChannel` is closed
and the per-subscriber buffer is drained, the subscriber receives
`onComplete` even if it has no outstanding `request(n)`. Likewise,
`onError` for a spec-violating `request(n <= 0)` (§3.9) is signalled
through the same single-threaded delivery path as `onNext` /
`onComplete`, preserving §1.3 signal serialization; subscribers do
not see those signals racing on the caller's thread.
====

[[async-channels-csp]]
== Coming from JCSP or GroovyCSP

Channels, select, preconditions and timer branches give `groovy.concurrent`
the core vocabulary of CSP, so process networks written with
https://www.cs.kent.ac.uk/projects/ofa/jcsp/[JCSP], or with the GroovyCSP
helpers (`PAR`, `ALT`) that shipped in GPars, translate shape for shape.
A process becomes an `async` task, a `PAR` becomes a scope, and the poison
pill that shuts a network down becomes `close()`:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=csp_network,indent=0]
----

Each stage reads until its input is closed and drained, then closes its own
output, so shutdown flows down the network just as poison does.
`AsyncScope.withScope` does not return until every process in it has
finished, and a failing process cancels the rest.

[cols="2,3", options="header"]
|===
| JCSP / GroovyCSP | `groovy.concurrent`

| `Channel.one2one()` (unbuffered)
| `AsyncChannel.create()`, a rendezvous channel: a send waits for its receive

| `Channel.one2one(new Buffer(n))`
| `AsyncChannel.create(n)`

| `any2one`, `one2any`, `any2any`
| Any `AsyncChannel`. Channel ends are not owned, so any task may send or receive

| `out.write(v)` / `in.read()`
| `await c.send(v)` / `await c.receive()`, or `for await (v in c)` to read until closed

| A `CSProcess`
| An `async { }` task, or a method that returns one

| `PAR`
| `AsyncScope.withScope { scope -> scope.async { … } … }`

| Poison
| `close()`. Receivers drain what was sent, then see the channel as closed

| `GDelta` and other copy-to-every-output processes
| `BroadcastChannel` and `subscribe()`, or `tap` for a single copy

| `ALT` with `priSelect()`
| `ChannelSelect.from(a, b).select()`, which prefers channels in list order

| `ALT` with `fairSelect()`
| `ChannelSelect.from(a, b).fair()`, built once and kept across calls

| `ALT` with `select()`, an arbitrary choice
| `random()`

| `select(boolean[] preCondition)`
| `receive(c).when { … }` on each offer, or `select(boolean... enabled)`

| `CSTimer` as an `ALT` guard
| `ChannelSelect.after(millis)` for a timeout that re-arms every round,
  or `AsyncChannel.after(millis)` for one fixed deadline

| Output guards (sending inside an `ALT`)
| `offers(send(c, v), receive(d))`

| `Barrier` (`sync`, `enroll`, `resign`)
| `java.util.concurrent.Phaser` (`arriveAndAwaitAdvance`, `register`, `arriveAndDeregister`)

| `Crew` (concurrent read, exclusive write)
| `@WithReadLock` / `@WithWriteLock`
|===

The rendezvous default matters when porting: a JCSP network that relies on
unbuffered channels for synchronisation should use `AsyncChannel.create()`,
not a buffered channel, or a producer will run ahead of its consumer.
JCSP's networked and mobile channels have no counterpart.

---

### Src Spec Doc  Core Gpars Migration (`src/spec/doc/_core-gpars-migration.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

[[gpars-migration]]
== Coming from GPars

Before Groovy 6, http://gpars.org/[GPars] was the usual library for
parallel collections, actors, agents and dataflow in Groovy. The
`groovy.concurrent` package covers most of the same ground, rebuilt around
virtual threads, structured concurrency and `async`/`await`. GPars still
works with Groovy 6, so existing code can keep using it and move over one
feature at a time, but new code rarely needs it. The tables below map each
GPars construct to its Groovy 6 counterpart.

The biggest change in style is that results are `Awaitable` values rather
than GPars `Promise` or `Future` objects, and that you `await` them instead
of calling `get()` or `getVal()`. `await` also accepts any
`java.util.concurrent.Future`, including the one GPars' `callAsync` returns.

[[gpars-migration-parallel]]
=== Parallel collections

[cols="2,3", options="header"]
|===
| GPars | Groovy 6

| `GParsPool.withPool { … }`, `withPool(n) { … }`
| `ParallelScope.withPool(Pool.cpu()) { scope -> … }`, `withPool(n) { scope -> … }`.
  Parallel methods also work outside any scope, on the common pool

| `withExistingPool(pool) { … }`
| `ParallelScope.withPool(pool) { scope -> … }` with a `Pool`

| `eachParallel`, `eachWithIndexParallel`, `collectParallel`,
  `collectManyParallel`, `findAllParallel`, `findParallel`,
  `findAnyParallel`, `grepParallel`, `splitParallel`, `anyParallel`,
  `everyParallel`, `countParallel`, `groupByParallel`, `injectParallel`
| Same names, on any `Collection`

| `sumParallel()`
| `sumParallel { a, b -> a + b }`. The accumulator is required

| `minParallel { it.age }`, `maxParallel()`
| `minParallel { a, b -> a.age <=> b.age }`. A two-argument comparator is required

| `foldParallel`
| `injectParallel`

| `makeConcurrent()`, `asConcurrent { }`, `ParallelEnhancer`
| Call the `…Parallel` methods directly

| `collection.parallel` (`map`, `filter`, `reduce` on a parallel array)
| `parallelStream()`, or chain the `…Parallel` methods

| `GParsExecutorsPool`
| `Pool.io()` or `Pool.virtual()`

| `executeAsync(…)`, `executeAsyncAndWait(…)`
| `async { }` per task, then `await Awaitable.all(…)`

| `speculate(…)`
| `await Awaitable.first(…)`, the first to succeed

| `runForkJoin(…)`
| `java.util.concurrent.RecursiveTask` on a `ForkJoinPool`
|===

GPars added its parallel methods to maps, strings and other iterable
objects as well. Groovy 6 adds them to `Collection` only, so call
`entrySet()`, `toList()` or similar first.

The closures passed to the Groovy 6 methods are converted to
`java.util.function` types, so their parameter count is fixed. For example,
`minParallel` and `maxParallel` take a two-argument comparator and do not
accept GPars' one-argument form.

[[gpars-migration-async]]
=== Asynchronous functions

[cols="2,3", options="header"]
|===
| GPars | Groovy 6

| `closure.callAsync(args)`
| `async { closure(args) }`

| `closure.asyncFun()`
| A closure or method that returns `async { … }`. See
  <<async-closure-factories,Async Closure Factories>>

| `Promise.then { … }`
| `awaitable.then { … }`, or plain sequential code after `await`

| `Dataflow.whenAllBound(a, b) { x, y -> … }`
| `def (x, y) = await(a, b)`
|===

[[gpars-migration-agents-actors]]
=== Agents and actors

[cols="2,3", options="header"]
|===
| GPars | Groovy 6

| `new Agent(0)`
| `Agent.create(0)`

| `agent << { updateValue(it + 1) }`
| `agent.send { it + 1 }`. The closure returns the new value

| `agent.val`, `agent.valAsync { … }`
| `await agent.getAsync()` waits for pending updates; `agent.get()` reads at once

| `agent.sendAndWait { … }`
| `await agent.sendAndGet { … }`

| `agent.addListener { oldValue, newValue -> … }`
| `for await (v in agent.changes())`, or any `Flow.Subscriber`

| `Actors.reactor { it * 2 }`
| `Actor.reactor { it * 2 }`

| `Actors.actor { loop { react { msg -> … } } }` holding state in local variables
| `Actor.stateful(initial) { state, msg -> … }`, returning the new state

| `Actors.messageHandler { when { String s -> … } }`, `DynamicDispatchActor`
| A `switch` on the message inside `Actor.reactor` or `Actor.stateful`

| `actor << msg`, `actor.send(msg)`
| `actor.send(msg)`

| `actor.sendAndWait(msg)`
| `await actor.sendAndGet(msg)`

| `actor.sendAndContinue(msg) { reply -> … }`
| `actor.sendAndGet(msg).then { reply -> … }`

| Nested `react` calls that change what the actor accepts next
| `ctx.become(handler)`, `ctx.stash()` and `ctx.unstashAll()` with the `ActorContext` handler forms

| `@groovyx.gpars.activeobject.ActiveObject`, `@ActiveMethod`
| `@groovy.transform.ActiveObject`, `@groovy.transform.ActiveMethod`.
  `blocking` defaults to `true` in both

| `DefaultPGroup`, `actor.parallelGroup = group`
| `ActorOptions.DEFAULTS.withExecutor(pool)`
|===

[[gpars-migration-dataflow]]
=== Dataflow

[cols="2,3", options="header"]
|===
| GPars | Groovy 6

| `Dataflow.task { … }`
| `async { … }`

| `DataflowVariable`, `v << value`
| `groovy.concurrent.DataflowVariable`, `v << value`

| `v.val`, `v.get()`
| `await v`

| `v.whenBound { … }`, `v.then { … }`
| `v.then { … }`

| `v.bindError(e)`
| `v.bindError(e)`

| `Dataflows`
| `groovy.concurrent.Dataflows`

| `DataflowQueue`
| `AsyncChannel.create(n)`. Buffers are bounded, where `DataflowQueue` is not

| `SyncDataflowQueue`
| `AsyncChannel.create()`, a rendezvous channel

| `DataflowBroadcast`, `createReadChannel()`
| `BroadcastChannel`, `subscribe()`

| `Dataflow.select(a, b)`
| `ChannelSelect.from(a, b)`

| `PoisonPill`
| `close()`

| `Dataflow.operator(…)`, `selector(…)`, `splitter(…)`, and channel methods such as `chainWith`, `filter` and `tap`
| An `async` loop over input channels, or `map`, `filter`, `merge`, `split` and `tap` on `AsyncChannel`
|===

GPars' CSP helpers (`PAR`, `ALT`) are covered in
<<async-channels-csp,Coming from JCSP or GroovyCSP>>.

[[gpars-migration-not-included]]
=== Not carried over

Some GPars features have no `groovy.concurrent` counterpart:

* Software transactional memory (`GParsStm`, built on Multiverse)
* Remote actors and remote dataflow
* `KanbanFlow`
* `LazyDataflowVariable`
* Dataflow operator lifecycle features such as event listeners,
  `StopGently` and pause/resume

Keep GPars for code that depends on them, or use a dedicated library for
that concern.

---

### Src Spec Doc  Design Pattern Abstract Factory (`src/spec/doc/_design-pattern-abstract-factory.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Abstract Factory Pattern

The http://en.wikipedia.org/wiki/Abstract_factory_pattern[Abstract Factory Pattern] provides a way to encapsulate a group of individual factories that have a common theme. It embodies the intent of a normal factory, i.e. remove the need for code using an interface to know the concrete implementation behind the interface, but applies to a set of interfaces and selects an entire family of concrete classes which implement those interfaces.

As an example, I might have interfaces Button, TextField and Scrollbar. I might have WindowsButton, MacButton, FlashButton as concrete classes for Button. I might have WindowsScrollBar, MacScrollBar and FlashScrollBar as concrete implementations for ScrollBar. Using the Abstract Factory Pattern should allow me to select which windowing system (i.e. Windows, Mac, Flash) I want to use once and from then on should be able to write code that references the interfaces but is always using the appropriate concrete classes (all from the one windowing system) under the covers.

== Example

Suppose we want to write a game system. We might note that many games have very similar features and control.

We decide to try to split the common and game-specific code into separate classes.

First let's look at the game-specific code for a http://en.wikipedia.org/wiki/Two-Up[Two-up] game:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=abstract_factory_example1,indent=0]
----

Now, let's look at the game-specific code for a number guessing game:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=abstract_factory_example2,indent=0]
----

Now, let's write our factory code:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=abstract_factory_code,indent=0]
----

The important aspect of this factory is that it allows selection of an entire family of concrete classes.

Here is how we would use the factory:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=abstract_factory_usage,indent=0]
----

Note that the first line configures which family of concrete game classes we will use. It's not important that we selected which family to use by using the factory property as shown in the first line. Other ways would be equally valid examples of this pattern. For example, we may have asked the user which game they wanted to play or determined which game from an environment setting.

With the code as shown, the game might look like this when run:

----
Welcome to the twoup game, you start with $1000
You have 1000, how much would you like to bet?
300
Draw
You have 1000, how much would you like to bet?
700
You win
You have 1700, how much would you like to bet?
1700
You lose
Sorry, you have no money left, goodbye
----

If we change the first line of the script to ++GameFactory.factory = guessFactory++, then the sample run might look like this:

-------------------------------------------------------------------
Welcome to the guessing game, my secret number is between 1 and 100
Enter a number between 1 and 100
75
Enter a number between 1 and 75
35
Enter a number between 1 and 35
15
Enter a number between 1 and 15
5
Enter a number between 5 and 15
10
Correct
-------------------------------------------------------------------

---

### Src Spec Doc  Design Pattern Adapter (`src/spec/doc/_design-pattern-adapter.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Adapter Pattern

The https://en.wikipedia.org/wiki/Adapter_pattern[Adapter Pattern] (sometimes called the wrapper pattern) allows objects satisfying one interface to be used where another type of interface is expected. There are two typical flavours of the pattern: the __delegation__ flavour and the __inheritance__ flavour.

== Delegation Example

Suppose we have the following classes:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_delegation_classes,indent=0]
----

We can ask the `RoundHole` class if a `RoundPeg` fits in it, but if we ask the same question for a `SquarePeg`, then it will fail because the `SquarePeg` class doesn't have a `radius` property (i.e. doesn't satisfy the required interface).

To get around this problem, we can create an adapter to make it appear to have the correct interface. It would look like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_delegation_code,indent=0]
----

We can use the adapter like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_delegation_usage,indent=0]
----

Which results in the following output:

----
peg SquarePegAdapter with peg width 4 (and notional radius 2.8284271247461903) fits in hole RoundHole with radius 4.0
peg SquarePegAdapter with peg width 5 (and notional radius 3.5355339059327378) fits in hole RoundHole with radius 4.0
peg SquarePegAdapter with peg width 6 (and notional radius 4.242640687119285) does not fit in hole RoundHole with radius 4.0
peg SquarePegAdapter with peg width 7 (and notional radius 4.949747468305833) does not fit in hole RoundHole with radius 4.0
----

== Inheritance Example

Let's consider the same example again using inheritance. First, here are the original classes (unchanged):

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_inheritance_classes,indent=0]
----

An adapter using inheritance:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_inheritance_code,indent=0]
----

Using the adapter:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_inheritance_usage,indent=0]
----

The output:

----
peg SquarePegAdapter with width 4 (and notional radius 2.8284271247461903) fits in hole RoundHole with radius 4.0
peg SquarePegAdapter with width 5 (and notional radius 3.5355339059327378) fits in hole RoundHole with radius 4.0
peg SquarePegAdapter with width 6 (and notional radius 4.242640687119285) does not fit in hole RoundHole with radius 4.0
peg SquarePegAdapter with width 7 (and notional radius 4.949747468305833) does not fit in hole RoundHole with radius 4.0
----

== Adapting using Closures

As a variation of the previous examples, we could instead define the following interface:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_closure_interface,indent=0]
----

We can then define an adapter as a closure as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_closure_define,indent=0]
----

And use it like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_closure_usage,indent=0]
----

== Adapting using the ExpandoMetaClass

As of Groovy 1.1, there is a built-in MetaClass which can automatically add properties and methods dynamically.

Here is how the example would work using that feature:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=adapter_expando_meta_class,indent=0]
----

After you create a peg object, you can simply add a property to it on the fly. No need to change the original class and no need for an adapter class.

---

### Src Spec Doc  Design Pattern Bouncer (`src/spec/doc/_design-pattern-bouncer.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Bouncer Pattern

The http://www.c2.com/cgi/wiki?BouncerPattern[Bouncer Pattern] describes usage of a method whose sole purpose is to either throw an exception (when particular conditions hold) or do nothing. Such methods are often used to defensively guard pre-conditions of a method.

When writing utility methods, you should always guard against faulty input arguments. When writing internal methods, you may be able to ensure that certain pre-conditions always hold by having sufficient unit tests in place. Under such circumstances, you may reduce the desirability to have guards on your methods.

Groovy differs from other languages in that you frequently use the `assert` method within your methods rather than having a large number of utility checker methods or classes.

== Null Checking Example

We might have a utility method such as:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=bouncer_null_check,indent=0]
----

And we would use it like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=bouncer_null_check_usage,indent=0]
----

But a more Groovy way to do this would simply be like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=bouncer_null_check_usage_groovy_way,indent=0]
----

== Validation Example

As an alternative example, we might have this utility method:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=bouncer_validation,indent=0]
----

And we would use it like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=bouncer_validation_usage,indent=0]
----

But with Groovy we could just as easily use:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=bouncer_validation_usage_groovy_way,indent=0]
----

---

### Src Spec Doc  Design Pattern Chain Of Responsibility (`src/spec/doc/_design-pattern-chain-of-responsibility.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Chain of Responsibility Pattern

In the Chain of Responsibility Pattern, objects using and implementing an interface (one or more methods) are intentionally loosely coupled. A set of objects that __implement__ the interface are organised in a list (or in rare cases a tree). Objects using the interface make requests from the first __implementor__ object. It will decide whether to perform any action itself and whether to pass the request further down the line in the list (or tree). Sometimes a default implementation for some request is also coded into the pattern if none of the implementors respond to the request.

== Example using traditional classes

In this example, the script sends requests to the `lister` object. The `lister` points to a `UnixLister` object. If it can't handle the request, it sends the request to the `WindowsLister`. If it can't handle the request, it sends the request to the `DefaultLister`.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility,indent=0]
----

The output will be a list of files (with slightly different format depending on the operating system).

Here is a UML representation:

[plantuml, ChainOfResponsibilityClasses, png]
....
!pragma layout smetana
skinparam nodesep 200
skinparam ObjectBorderColor<<Hidden>> Transparent
skinparam ObjectBackgroundColor<<Hidden>> Transparent
skinparam ObjectFontColor<<Hidden>> Transparent
skinparam ObjectStereotypeFontColor<<Hidden>> Transparent
class UnixLister {
    nextInLine : Object
    +listFiles(dir)
}
object dummy1<<Hidden>>
class WindowsLister {
    nextInLine : Object
    +listFiles(dir)
}
object dummy2<<Hidden>>
class DefaultLister {
    +listFiles(dir)
}
hide DefaultLister fields
object script
script ..r..> "<<use>>" UnixLister
UnixLister --> "forwardIfRequired" WindowsLister
UnixLister <-[hidden]- dummy1
WindowsLister <-[hidden]- dummy2
WindowsLister --> "forwardIfRequired" DefaultLister
hide <<Hidden>>
....

== Example using simplifying strategies

For simple cases, consider simplifying your code by not requiring the chain of classes.
Instead, use Groovy truth and the elvis operator as shown here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility_elvis,indent=0]
----

Or Groovy's switch as shown here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility_switch,indent=0]
----

Alternatively, for Groovy 3+, consider using streams of lambdas as shown here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility_lambda,indent=0]
----

== When not to use

If your use of chain of responsibility involves frequent use of the `instanceof` operator, like here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility_shape,indent=0]
----
<1> instanceof code smell

It could indicate that instead of using the chain of responsibility pattern, you might consider
using richer types, perhaps in combination with Groovy's multimethods. For example, perhaps this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility_shape_multimethods,indent=0]
----

or using more traditional object-oriented style like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=chain_of_responsibility_shape_oo,indent=0]
----

== Going further

Other variations to this pattern:

* we could have an explicit interface in the traditional example, e.g. `Lister`, to statically type the implementations but because of _duck-typing_ this is optional
* we could use a chain tree instead of a list, e.g. `if (animal.hasBackbone())` delegate to `VertebrateHandler` else delegate to `InvertebrateHandler`
* we could always pass down the chain even if we processed a request (no early return)
* we could decide at some point to not respond and not pass down the chain (pre-emptive abort)
* we could use Groovy’s meta-programming capabilities to pass unknown methods down the chain, e.g. combine
chain of responsibility with the use of `methodMissing`

---

### Src Spec Doc  Design Pattern Command (`src/spec/doc/_design-pattern-command.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Command Pattern


The https://en.wikipedia.org/wiki/Command_pattern[Command Pattern] is a pattern for
loosely coupling a client object which wants to execute a series of commands and
receiver objects which enact those commands.
Instead of talking to receivers directly, clients interact with an intermediary object
which then relays the necessary commands to the receivers.
The pattern is in common use within the JDK, for example the api:javax.swing.Action[] class in Swing
decouples swing code from receivers like buttons, menu items and panels.

The class diagram showing the typical classes is:

[plantuml, CommandClasses, png]
....
!pragma layout smetana
skinparam nodesep 100
hide fields
interface Command {
    +execute(String command)
}
object client
class Command1 implements Command {
    +execute(String command)
}
class Receiver1 {
    +action1(args1)
}
client ..r..> "command" Command
Command1 --r--> Receiver1
....

The sequence of interactions is as shown below for an arbitrary receiver:

[plantuml, CommandSequence, png]
....
!pragma layout smetana
client -> intermediary: command
intermediary -> receiverN: actionN
....

== Example with traditional classes

The relevant classes required for turning a light on and off (see the example in the earlier wikipedia reference)
would be as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=command_traditional,indent=0]
----

Our client scripts sends `execute` commands to an intermediary and knows nothing
about any specific receivers, or any specific action method names and arguments.

== Simplifying variations

Given that Groovy has first-class function support, we can do away with the
actual command classes (like `SwitchOnCommand`) by instead using closures as shown here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=command_closures,indent=0]
----
<1> Command closures (here method closures) but could be lambdas/method references for Groovy 3+

We can simplify further using the JDK's existing `Runnable` interface
and using a switch map rather than a separate `Switch` class as shown here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=command_lambda,indent=0]
----

We have added an additional `Door` receiver to illustrate how to expand the original example.
Running this script results in:

----
The light is on
The light is off
The door is unlocked
----

As a variation, if the command names aren't important to us,
we can forgo using the switch map and just have a list of tasks to invoke as shown here:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=command_lambda_variant,indent=0]
----

---

### Src Spec Doc  Design Pattern Composite (`src/spec/doc/_design-pattern-composite.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Composite Pattern

The https://en.wikipedia.org/wiki/Composite_pattern[Composite Pattern] allows you to treat single instances of an object the same way as a group of objects. The pattern is often used with hierarchies of objects. Typically, one or more methods should be callable in the same way for either __leaf__ or __composite__ nodes within the hierarchy. In such a case, composite nodes typically invoke the same named method for each of their children nodes.

== Example

Consider this usage of the composite pattern where we want to call `toString()` on either `Leaf` or `Composite` objects.

[plantuml, CompositeClasses, png]
....
!pragma layout smetana
skinparam linetype ortho
skinparam nodesep 100
class Component {
    +toString()
}
class Leaf {
    +toString()
}
class Composite {
    +toString()
}
object componentClient
hide fields
componentClient ..r..> "<<use>>" Component
Component <|-- Leaf
Composite "1" *-- "*" Component : children
Component <|-- Composite
....

In Java, the `Component` class is essential as it provides the type used for both leaf and composite nodes. In Groovy, because of duck-typing, we don't need it for that purpose, however, it can still serve as a useful place to place common behaviour between the leaf and composite nodes.

For our purposes, we will assemble the following hierarchy of components.

[plantuml, CompositeComponents, png]
....
!pragma layout smetana
object root
object "leaf A" as leafA
object "comp B" as compB
object "leaf C" as leafC
object "leaf B1" as leafB1
object "leaf B2" as leafB2

root -- leafA
root -- compB
root -- leafC
compB -- leafB1
compB -- leafB2
....

Here is the code:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=composite_code,indent=0]
----

Here is the resulting output:

----
root
-leaf A
-comp B
--leaf B1
--leaf B2
-leaf C
----

---

### Src Spec Doc  Design Pattern Decorator (`src/spec/doc/_design-pattern-decorator.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Decorator Pattern

The https://en.wikipedia.org/wiki/Decorator_pattern[Decorator Pattern] provides a mechanism to embellish the behaviour of an object without changing its essential interface. A decorated object should be able to be substituted wherever the original (non-decorated) object was expected. Decoration typically does not involve modifying the source code of the original object and decorators should be able to be combined in flexible ways to produce objects with several embellishments.

== Traditional Example

Suppose we have the following `Logger` class.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_logger_class,indent=0]
----

There might be times when it is useful to timestamp a log message, or times when we might want to change the case of the message. We could try to build all of this functionality into our `Logger` class. If we did that, the `Logger` class would start to be very complex. Also, everyone would obtain all of the features even when they might want only a small subset of the features. Finally, feature interaction would become quite difficult to control.

To overcome these drawbacks, we instead define two decorator classes. Uses of the `Logger` class are free to embellish their base logger with zero or more decorator classes in whatever order they desire. The classes look like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_traditional_classes,indent=0]
----

We can use the decorators like so:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_traditional_usage,indent=0]
----

You can see that we embellish the logger behaviour with both decorators. Because of the order we chose to apply the decorators, our log message comes out capitalised and the timestamp is in normal case. If we swap the order around, let's see what happens:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_traditional_usage2,indent=0]
----

Now the timestamp itself has also been changed to be uppercase.

== Simplifying with closures or lambdas

Closures make it easy to represent code. We can use that fact to
make a general purpose logger class that accepts the decoration code as a closure.
This saves us defining many decoration classes.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorating_logger_closure,indent=0]
----

We can use the same approach with lambdas:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorating_logger_lambda,indent=0]
----

== A touch of dynamic behaviour

Our previous decorators were specific to `Logger` objects. We can use Groovy's Meta-Object Programming capabilities to create a decorator which is far more general purpose in nature. Consider this class:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_dynamic_behaviour_class,indent=0]
----

It takes any class and decorates it so that any `String` method parameter will automatically be changed to lower case.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_dynamic_behaviour_usage,indent=0]
----

Just be careful with ordering here. The original decorators were restricted to decorating `Logger` objects. This decorator works with any object type, so we can't swap the ordering around, i.e. this won't work:

----
// Can't mix and match Interface-Oriented and Generic decorators
// logger = new TimeStampingLogger(new GenericLowerDecorator(new Logger()))
----

We could overcome this limitation be generating an appropriate Proxy type at runtime but we won't complicate the example here.

== Runtime behaviour embellishment

You can also consider using the `ExpandoMetaClass` from Groovy 1.1 to dynamically embellish a class with behaviour. This isn't the normal style of usage of the decorator pattern (it certainly isn't nearly as flexible) but may help you to achieve similar results in some cases without creating a new class.

Here's what the code looks like:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_runtime_behaviour,indent=0]
----

This achieves a similar result to applying a single decorator but we have no way to easily apply and remove embellishments on the fly.

== More dynamic decorating

Suppose we have a calculator class (Actually any class would do).

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_calc_class,indent=0]
----

We might be interested in observing usage of the class over time. If it is buried deep within our codebase, it might be hard to determine when it is being called and with what parameters. Also, it might be hard to know if it is performing well. We can easily make a generic tracing decorator that prints out tracing information whenever any method on the `Calc` class is called and also provide timing information about how long it took to execute. Here is the code for the tracing decorator:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_tracing_decorator,indent=0]
----

Here is how to use the class in a script:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_tracing_decorator_usage,indent=0]
----

And here is what you would see after running this script:

----
Calling add{3, 12}
Got 15 in 31 ms
----

== Decorating with an Interceptor

The above timing example hooks into the lifecycle of Groovy objects (via `invokeMethod`). This is such an important style performing meta-programming that Groovy has special support for this style of decorating using __interceptors__.

Groovy even comes with a built-in `TracingInterceptor`. We can extend the built-in class like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_interceptor,indent=0]
----

Here is an example of using this new class:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_interceptor_usage,indent=0]
----

And here is the output:

----
before Calc.ctor()
after  Calc.ctor()
Duration: 0 ms
before Calc.add(java.lang.Integer, java.lang.Integer)
after  Calc.add(java.lang.Integer, java.lang.Integer)
Duration: 2 ms
----

== Decorating with java.lang.reflect.Proxy

If you are trying to decorate an object (i.e. just a particular instance of the class, not the class generally), then you can use Java's `java.lang.reflect.Proxy`. Groovy makes working with this easier than just Java. Below is a code sample taken out of a grails project that wraps a `java.sql.Connection` so that it's close method is a no-op:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_reflect_proxy,indent=0]
----

If there were many methods to intercept, then this approach could be modified to look up closure in a map by method name and invoke it.

== Decorating with Spring

The https://spring.io/[Spring Framework] allows decorators to be applied with __interceptors__ (you may have heard the terms __advice__ or __aspect__). You can leverage this mechanism from Groovy as well.

First define a class that you want to decorate (we'll also use an interface as is normal Spring practice):

Here's the interface:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_spring_calc,indent=0]
----

Here's the class:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_spring_calc_impl,indent=0]
----

Now, we define our wiring in a file called `beans.xml` as follows:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:lang="http://www.springframework.org/schema/lang"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/lang https://www.springframework.org/schema/lang/spring-lang.xsd">

    <bean id="performanceInterceptor" autowire="no"
          class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor">
        <property name="loggerName" value="performance"/>
    </bean>
    <bean id="calc" class="util.CalcImpl"/>
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames" value="calc"/>
        <property name="interceptorNames" value="performanceInterceptor"/>
    </bean>
</beans>
----

Now, our script looks like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_spring_context,indent=0]
----

And when we run it, we see the results:

----
21/05/2007 23:02:35 org.springframework.aop.interceptor.PerformanceMonitorInterceptor invokeUnderTrace
FINEST: StopWatch 'util.Calc.add': running time (millis) = 16
----

You may have to adjust your `logging.properties` file for messages at log level `FINEST` to be displayed.

== Asynchronous Decorators using Awaitable

The following example is inspired by some of the early example code for the
http://design.cs.iastate.edu/~panini/[Panini] programming language.
These days, you'll see this style used with async functions in JavaScript.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=decorator_async,indent=0]
----

---

### Src Spec Doc  Design Pattern Delegation (`src/spec/doc/_design-pattern-delegation.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Delegation Pattern

The https://en.wikipedia.org/wiki/Delegation_pattern[Delegation Pattern] is a technique where an object's behavior (public methods) is implemented by delegating responsibility to one or more associated objects.

Groovy allows the traditional style of applying the delegation pattern, e.g. see https://refactoring.com/catalog/replaceSuperclassWithDelegate.html[Replace Inheritance with Delegation].

== Implement Delegation Pattern using ExpandoMetaClass

The gapi:groovy.lang.ExpandoMetaClass[] allows usage of this pattern to be encapsulated in a library. This allows Groovy to emulate similar libraries available for the Ruby language.

Consider the following library class:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_delegator,indent=0]
----

With this in your classpath, you can now apply the delegation pattern dynamically as shown in the following examples. First, consider we have the following classes:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_classes,indent=0]
----

We can now use the __delegator__ to automatically borrow methods from the __lender__ object to extend the __Person__ class. We can borrow the methods as is or with a rename:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_usage,indent=0]
----

The first line above, adds the __borrowFor__ method to the __Person__ class by delegating to the __lender__ object. The second line adds a __getMoney__ method to the __Person__ class by delegating to the __lender__ object's __borrowAmount__ method.

Alternatively, we could borrow multiple methods like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_usage2,indent=0]
----

Which adds these two methods to the __Person__ class.

Or if we want all the methods, like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_usage3,indent=0]
----

Which will make all the methods in the delegate object available in the __Person__ class.

Alternatively, we can use a map notation to rename multiple methods:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_usage4,indent=0]
----

== Implement Delegation Pattern using @Delegate annotation

Since version 1.6 you can use the built-in delegation mechanism which is based on AST transformation.

This make delegation even easier:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=delegation_annotation,indent=0]
----

---

### Src Spec Doc  Design Pattern Flyweight (`src/spec/doc/_design-pattern-flyweight.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////
ifndef::reldir_root[]
:reldir_root: .
endif::[]

= Flyweight Pattern

The http://en.wikipedia.org/wiki/Flyweight_pattern[Flyweight Pattern] is a pattern for greatly reducing memory requirements by not requiring that heavy-weight objects be created in large numbers when dealing with systems that contain many things that are mostly the same. If for instance, a document was modelled using a complex character class that knew about unicode, fonts, positioning, etc., then the memory requirements could be quite large for large documents if each physical character in the document required its own character class instance. Instead, characters themselves might be kept within Strings and we might have one character class (or a small number such as one character class for each font type) that knew the specifics of how to deal with characters.

In such circumstances, we call the state that is shared with many other things (e.g. the character type) __intrinsic__ state. It is captured within the heavy-weight class. The state which distinguishes the physical character (maybe just its ASCII code or Unicode) is called its __extrinsic__ state.

== Example

First we are going to model some complex aircraft (the first being a hoax competitor of the second - though that is not relevant to the example).

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=flyweight_boeing797,indent=0]
----

image::{reldir_root}/assets/img/b797-hoax.jpg[]

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=flyweight_airbus380,indent=0]
----

image::{reldir_root}/assets/img/a380.jpg[]

If we want to model our fleet, our first attempt might involve using many instances of these heavy-weight objects. It turns out though that only a few small pieces of state (our extrinsic state) change for each aircraft, so we will have singletons for the heavy-weight objects and capture the extrinsic state (bought date and asset number in the code below) separately.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=flyweight_factory,indent=0]
----

So here, even if our fleet contained hundreds of planes, we would only have one heavy-weight object for each type of aircraft.

As a further efficiency measure, we might use lazy creation of the flyweight objects rather than create the initial map up front as in the above example.

Running this script results in:

----
Asset Number: 1001
Capacity: 555 people
Speed: 912 km/h
Range: 10370 km
Bought: 10-May-2007

Asset Number: 1002
Capacity: 555 people
Speed: 912 km/h
Range: 10370 km
Bought: 10-Nov-2007

Asset Number: 1003
Capacity: 1000 people
Speed: 1046 km/h
Range: 14400 km
Bought: 10-May-2008

Asset Number: 1004
Capacity: 1000 people
Speed: 1046 km/h
Range: 14400 km
Bought: 10-Nov-2008
----

---

### Src Spec Doc  Design Pattern Iterator (`src/spec/doc/_design-pattern-iterator.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Iterator Pattern


The https://en.wikipedia.org/wiki/Iterator_pattern[Iterator Pattern] allows sequential access to the elements of an aggregate object without exposing its underlying representation.

Groovy has the iterator pattern built right in to many of its closure operators, e.g. `each` and `eachWithIndex` as well as the `for .. in` loop.

For example:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=iterator_example,indent=0]
----

Results in the output:

----
1
2
3
4
May=31
Mar=31
Apr=30
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=255,g=255,b=255]
----

Another example:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=iterator_example2,indent=0]
----

Results in:

----
Position 0 contains 'java.awt.Color[r=0,g=0,b=0]'
Position 1 contains 'java.awt.Color[r=255,g=255,b=255]'
----

The iterator pattern is also built in to other special operators such as the `eachByte`, `eachFile`, `eachDir`, `eachLine`, `eachObject`, `eachMatch` operators for working with streams, URLs, files, directories and regular expressions matches.

---

### Src Spec Doc  Design Pattern Loan My Resource (`src/spec/doc/_design-pattern-loan-my-resource.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Loan my Resource Pattern

The https://wiki.scala-lang.org/display/SYGN/Loan[Loan my Resource] pattern ensures that a resource is deterministically disposed of once it goes out of scope.

This pattern is built in to many Groovy helper methods. You should consider using it yourself if you need to work with resources in ways beyond what Groovy supports.

== Example

Consider the following code which works with a file. First we might write some line to the file and then print its size:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=loan_my_resource_example,indent=0]
----

We could also read back the contents of the file a line at a time and print each line out:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=loan_my_resource_example2,indent=0]
----

Note that normal Java `Reader` and `PrintWriter` objects were used under the covers by Groovy but the code writer did not have to worry about explicitly creating or closing those resources. The built-in Groovy methods loan the respective reader or writer to the closure code and then tidy up after themselves. So, you are using this pattern without having to do any work.

Sometimes however, you wish to do things slightly differently to what you can get for free using Groovy's built-in mechanisms. You should consider utilising this pattern within your own resource-handling operations.

Consider how you might process the list of words on each line within the file. We could actually do this one too using Groovy's built-in functions, but bear with us and assume we have to do some resource handling ourselves. Here is how we might write the code without using this pattern:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=loan_my_resource_example3,indent=0]
----

Notice that we now have an explicit call to `close()` in our code. If we didn't code it just right (here we didn't surround the code in a ``try ... finally`` block, we run the risk of leaving the file handle open.

Let's now apply the loan pattern. First, we'll write a helper method:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=loan_my_resource_example4,indent=0]
----

Now, we can re-write our code as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=loan_my_resource_example5,indent=0]
----

This is much simpler and has removed the explicit `close()`. This is now catered for in one spot so we can apply the appropriate level of testing or reviewing in just one spot to be sure we have no problems.

---

### Src Spec Doc  Design Pattern Monoid (`src/spec/doc/_design-pattern-monoid.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Using Monoids


https://en.wikipedia.org/wiki/Monoid#Monoids_in_computer_science[Monoids] allow
the mechanics of an aggregation algorithm to be separated from the algorithm-specific logic associated with that aggregation.
It is often thought to be a functional design pattern.

Perhaps, it is easiest seen with an example. Consider the code for integer sum, integer product and string concatenation.
We might note various similarities:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_intro,indent=0]
----
<1> Initialize an aggregate counter
<2> Loop throw elements with for/while/iteration adjusting counter

We can remove the duplicate aggregation coding and the tease out the important differences for each algorithm.
We might instead use Groovy's `inject` method. This is a _fold_ operation in functional programming jargon.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_inject,indent=0]
----

Here the first parameter is the initial value, and the supplied closure contains the algorithm-specific logic.

Similarly, for Groovy 3+, we can use the JDK stream API and lambda syntax as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_lambdas,indent=0]
----

== A touch of formalism

Looking at these examples, we might think all aggregation can be supported this way.
In fact, we look for certain characteristics to ensure that this aggregation pattern will apply:

* Closure: performing the aggregation step should produce a result of the same type as the elements being aggregated.
****
Examples: `1L + 3L` produces a `Long`, and `'foo' + 'bar'` produces a `String`. +
Non-monoid examples: `'foo'.size() + 'bar'.size()` (takes strings, returns an integer),
the type _odd numbers_ with respect to addition, algorithms which don't handle null arguments if such arguments are possible.
****
[NOTE]
====
When using the term _closure_ here, we simply mean closed under the operation, not the Groovy `Closure` class.
====
* Associativity: the order in which we apply the aggregation step should not matter.
****
Examples: `(1 + 3) + 5` is the same as `1 + (3 + 5)`, and `('a' + 'b') + 'c'` is the same as `'a' + ('b' + 'c')`. +
Non-monoid example: `(10 - 5) - 3` is not equal to `10 - (5 - 3)` therefore integers are not a monoid with respect to subtraction.
****
* Identity element (sometimes also called a 'zero' element):
there should be an element which aggregated with any element returns the original element.
****
Examples: `0 + 42 == 42`, `42 + 0 == 42`, `1 * 42 == 42`, and `'' + 'foo' == 'foo'`. +
Non-monoid example: the type _non-empty strings_ is not a monoid with respect to concatenation.
****

If your algorithm doesn't satisfy all the monoid properties, that doesn't mean aggregation isn't possible.
It just means that you won't get all the benefits from monoids, which we'll cover shortly, or you might have
a little more work to do.
Also, you might be able to convert your data structures slightly to turn your problem into one involving monoids.
We'll cover that topic a little later in this section.

== Benefits of monoids

Consider adding the integers 10 through 16.
Because the operation of addition for integers is a monoid, we already know that we can save writing code
and instead use the approach we saw in the earlier `inject` examples.
There are some other nice properties.

Because of the _closure_ property,
if we have a pairwise method like `sum(Integer a, Integer b)`, then for a monoid, we can always
extend that method to work with a list, e.g. `sum(List<Integer> nums)` or `sum(Integer first, Integer... rest)`.

Because of _associativity_,
we can employ some interesting ways to solve the aggregation including:

* Divide and conquer algorithms which break the problem into smaller pieces
* Various incremental algorithms for example memoization would allow summing from 1..5
to potentially start part way through be reusing a cached value of summing 1..4 if that had been calculated earlier
* Inherent parallelization can make use of multiple cores

Let's just look at the first of these in more detail. With a multicore
processor, one core could add `10` plus `11`, another core `12` plus `13`, and so on.
We'd use the _identity_ element if needed (shown being added to `16` in our example).
Then the intermediate results could also be added together concurrently and so on until the result was reached.

[plantuml, MonoidAddition, png]
....
!pragma layout smetana
skinparam shadowing false
skinparam ClassFontSize 18
skinparam ClassBackgroundColor<<Identity>> Transparent
skinparam ClassBorderColor<<Identity>> grey
skinparam ClassStereotypeFontSize<<Identity>> 4
skinparam ClassStereotypeFontColor<<Identity>> Transparent
hide circle
class " 0 " as zero << (I,lightgrey) Identity >>
show zero circle
class " 10 " as a1
class " 11 " as a2
class " 12 " as a3
class " 13 " as a4
class " 14 " as a5
class " 15 " as a6
class " 16 " as a7
class " 21 " as b1
class " 25 " as b2
class " 29 " as b3
class " 16 " as b4
class " 46 " as c1
class " 45 " as c2
class " 91 " as d1
a1 .r[hidden].> a2
a2 .r[hidden].> a3
a3 .r[hidden].> a4
a4 .r[hidden].> a5
a5 .r[hidden].> a6
a6 .r[hidden].> a7
a7 .r[hidden].> zero
b1 <.d. a1
b1 <.d. a2
b2 <.d. a3
b2 <.d. a4
b3 <.d. a5
b3 <.d. a6
b4 <.d. a7
b4 <.d. zero
c1 <.d. b1
c1 <.d. b2
c2 <.d. b3
c2 <.d. b4
d1 <.d. c1
d1 <.d. c2
hide empty members
....

We have reduced the amount of code we need to write, and we also have potential performance gains.

Here is how we might code the previous example using Groovy's
parallel collections:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_parallel,indent=0]
----

== Working with Non-monoids

Suppose we want to find the average of the numbers 1..10. Groovy has a built-in method for this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_1to10,indent=0]
----

Now, suppose we want to build our own monoid solution instead of using the built-in version.
It might seem difficult to find the _identity_ element. After all:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_0to10,indent=0]
----

Similarly, if we are tempted to write the pairwise aggregation closure it might be something like:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_bad,indent=0]
----

What `b` can we use for the _identity_ element here so that our equation returns the original?
We need to use `a`, but that isn't a fixed value, so there is no _identity_.

Also, associativity doesn't hold for this initial attempt at defining `avg` as these examples show:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_assoc,indent=0]
----

Also, what about our _closure_ property? Our original numbers were integers, but our average (`5.5`)
is not. We can solve this by making our average work for any `Number` instances, but it might not always be this easy.

It might appear that this problem is not amenable to a monoidal solution.
However, there are numerous ways to bring monoids into the solution.

We can split it into two parts:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_split,indent=0]
----

The calculation of `sum()` can follow monoid rules and then our last step can calculate the average.
We can even do a parallel version:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_split_parallel,indent=0]
----

Here, we were using the built-in `sum()` method (and `sumParallel()` for the parallel example),
but if you were doing it by hand, the monoid nature of that part of your calculation would
make it easier to write your own code for that step.

Alternatively, we can introduce a helper data structure that reworks the problem to be a monoid.
Instead of just keeping the total, let's keep a list containing the total and count of numbers.
The code could look something like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_reworked_simple,indent=0]
----

Or, to be a little fancier, we could introduce a class for our data structure and even calculate
in parallel:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=monoids_average_reworked_parallel,indent=0]
----

---

### Src Spec Doc  Design Pattern Null Object (`src/spec/doc/_design-pattern-null-object.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Null Object Pattern


The https://en.wikipedia.org/wiki/Null_object_pattern[Null Object Pattern] involves using a special object place-marker object representing null. Typically, if you have a reference to null, you can't invoke `reference.field` or `reference.method()` You receive the dreaded `NullPointerException`. The null object pattern uses a special object representing null, instead of using an actual `null`. This allows you to invoke field and method references on the null object. The result of using the null object should semantically be equivalent to __doing nothing__.

== Simple Example

Suppose we have the following system:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=null_object_simple_example,indent=0]
----

When run, this prints out `1200`. Suppose now that we now invoke:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=null_object_simple_example2,indent=0]
----

If we now try to calculate `biggestSalary` again, we receive a null pointer exception.

To overcome this problem, we can introduce a `NullJob` class and change the above statement to become:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=null_object_simple_example3,indent=0]
----

This works as we require but it's not always the best way to do this with Groovy. Groovy's safe-dereference operator (`?.`) operator and null aware closures often allow Groovy to avoid the need to create a special null object or null class. This is illustrated by examining a groovier way to write the above example:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=null_object_simple_example4,indent=0]
----

Two things are going on here to allow this to work. First of all, `max()` is __'null aware'__ so that ++[300, null, 400].max() == 400++. Secondly, with the `?.` operator, an expression like `p?.job?.salary` will be equal to null if `salary` is equal to null, or if `job` is equal ` null or if `p` is equal to null. You don't need to code a complex nested ++if ... then ... else++ to avoid a `NullPointerException`.

== Tree Example

Consider the following example where we want to calculate size, cumulative sum and cumulative product of all the values in a tree structure.

Our first attempt has special logic within the calculation methods to handle null values.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=null_object_tree_example,indent=0]
----

If we introduce the null object pattern (here by defining the `NullTree` class), we can now simplify the logic in the `size()`, `sum()` and`product()` methods. These methods now much more clearly represent the logic for the normal (and now universal) case. Each of the methods within `NullTree` returns a value which represents doing nothing.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=null_object_tree_example2,indent=0]
----

The result of running either of these examples is:

----
4
14
120
----

Note: a slight variation with the null object pattern is to combine it with the singleton pattern. So, we wouldn't write ++new NullTree()++ wherever we needed a null object as shown above. Instead we would have a single null object instance which we would place within our data structures as needed.

---

### Src Spec Doc  Design Pattern Observer (`src/spec/doc/_design-pattern-observer.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Observer Pattern


The https://en.wikipedia.org/wiki/Observer_pattern[Observer Pattern] allows one or more _observers_ to be notified
about changes or events from a _subject_ object.

[plantuml, ObserverClasses, png]
....
!pragma layout smetana
skinparam ClassBorderColor<<Hidden>> Transparent
skinparam ClassBackgroundColor<<Hidden>> Transparent
skinparam ClassStereotypeFontColor<<Hidden>> Transparent
skinparam ClassFontSize<<Hidden>> 24
skinparam ClassFontStyle<<Hidden>> bold
skinparam shadowing<<Hidden>> false
hide <<Hidden>> circle
class "..." as ConcreteHidden
class ConcreteHidden <<Hidden>> {
}
class Observer {
    +update()
}
class ConcreteObserver1 {
    +update()
}
class ConcreteObserverN {
    +update()
}
hide Observer fields
class Subject {
    -observerCollection
    +registerObserver(observer)
    +unregisterObserver(observer)
    +notifyObservers()
}
Observer <|-- ConcreteObserver1
Observer <|-[hidden]- ConcreteHidden
Observer <|-- ConcreteObserverN
Observer ---r---o Subject
ConcreteObserver1 .r[hidden]. ConcreteHidden
....

== Example

Here is a typical implementation of the classic pattern:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=observer_classic,indent=0]
----

Using Closures, we can avoid creating the concrete observer classes as shown below:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=observer_closures,indent=0]
----

As a variation for Groovy 3+, let's consider dropping the `Observer` interface and using lambdas as shown below:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=observer_lambdas,indent=0]
----

We are now calling the `accept` method from `Consumer` rather
than the `update` method from `Observer`.

== @Bindable and @Vetoable

The JDK has some built-in classes which follow the observer pattern.
The `java.util.Observer` and `java.util.Observable` classes are deprecated from JDK 9 due to various limitations.
Instead, you are recommended to use various more powerful classes in the `java.beans` package such as `java.beans.PropertyChangeListener`.
Luckily, Groovy has some built-in transforms (gapi:groovy.beans.Bindable[] and gapi:groovy.beans.Vetoable[])
which support for some key classes from that package.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=observer_bindable,indent=0]
----

Here, methods like `addPropertyChangeListener` perform the same role as `registerObserver` in previous examples.
There is a `firePropertyChange` method corresponding to `notifyAll`/`notifyObservers` in previous examples but Groovy adds that
automatically here, so it isn't visible in the source code. There is also a `propertyChange` method that corresponds
to the `update` method in previous examples, though again, that isn't visible here.

---

### Src Spec Doc  Design Pattern Pimp My Library (`src/spec/doc/_design-pattern-pimp-my-library.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Pimp my Library Pattern


The http://www.artima.com/weblogs/viewpost.jsp?thread=179766[Pimp my Library] Pattern suggests an approach for extending a library that nearly does everything that you need but just needs a little more. It assumes that you do not have source code for the library of interest.

== Example

Suppose we want to make use of the built-in Integer facilities in Groovy (which build upon the features already in Java). Those libraries have nearly all of the features we want but not quite everything. We may not have all of the source code to the Groovy and Java libraries so we can't just change the library. Instead we augment the library. Groovy has a number of ways to do this. One way is to use a Category.

First, we'll define a suitable category.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=pimp_my_library_example,indent=0]
----

We have added two methods which augment the Integer methods by providing the `greaterThanAll` method. Categories follow conventions where they are defined as static methods with a special first parameter representing the class we wish to extend. The ++greaterThanAll(Integer self, others)++ static method becomes the `greaterThanAll(other)` instance method.

We defined two versions of `greaterThanAll`. One which works for collections, ranges etc. The other which works with a variable number of `Integer` arguments.

Here is how you would use the category.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=pimp_my_library_example2,indent=0]
----

As you can see, using this technique you can effectively enrich an original class without having access to its source code. Moreover, you can apply different enrichments in different parts of the system as well as work with un-enriched objects if we need to.

---

### Src Spec Doc  Design Pattern Proxy (`src/spec/doc/_design-pattern-proxy.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Proxy Pattern

The https://en.wikipedia.org/wiki/Proxy_pattern[Proxy Pattern] allows one object to act as a pretend replacement for some other object. In general, whoever is using the proxy, doesn't realise that they are not using the real thing. The pattern is useful when the real object is hard to create or use: it may exist over a network connection, or be a large object in memory, or be a file, database or some other resource that is expensive or impossible to duplicate.

== Example

One common use of the proxy pattern is when talking to remote objects in a different JVM. Here is the client code for creating a proxy that talks via sockets to a server object as well as an example usage:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=proxy_client,indent=0]
----

Here is what your server code might look like (start this first):

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=proxy_server,indent=0]
----

---

### Src Spec Doc  Design Pattern Singleton (`src/spec/doc/_design-pattern-singleton.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Singleton Pattern


The http://en.wikipedia.org/wiki/Singleton_pattern[Singleton Pattern] is used to make sure only one object of a particular class is ever created. This can be useful when exactly one object is needed to coordinate actions across a system; perhaps for efficiency where creating lots of identical objects would be wasteful, perhaps because a particular algorithm needing a single point of control is required or perhaps when an object is used to interact with a non-shareable resource.

Weaknesses of the Singleton pattern include:

- It can reduce reuse. For instance, there are issues if you want to use inheritance with Singletons. If `SingletonB` extends `SingletonA`, should there be exactly (at most) one instance of each or should the creation of an object from one of the classes prohibit creation from the other. Also, if you decide both classes can have an instance, how do you override the `getInstance()` method which is static?
- It is also hard to test singletons in general because of the static methods but Groovy can support that if required.

== Example: The Classic Java Singleton

Suppose we wish to create a class for collecting votes. Because getting the right number of votes may be very important, we decide to use the singleton pattern. There will only ever be one `VoteCollector` object, so it makes it easier for us to reason about that objects creation and use.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_vote_collector,indent=0]
----

Some points of interest in this code:

- it has a private constructor, so no `VoteCollector` objects can be created in our system (except for the `INSTANCE` we create)
- the `INSTANCE` is also private, so it can't be changed once set
- we haven't made the updating of votes thread-safe at this point (it doesn't add to this example)
- the vote collector instance is not lazily created (if we never reference the class, the instance won't be created; however, as soon as we reference the class, the instance will be created even if not needed initially)

We can use this singleton class in some script code as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_vote_collector_usage,indent=0]
----

Here we used the instance 3 times. The second usage was even in a different thread (but don't try this in a scenario with a new class loader).

Running this script yields (your hashcode value will vary):

----
Collector:15959960, Votes:0
Collector:15959960, Votes:1
Collector:15959960, Votes:2
----

Variations to this pattern:

- To support lazy-loading and multi-threading, we could just use the `synchronized` keyword with the `getInstance()` method. This has a performance hit but will work.
- We can consider variations involving double-checked locking and the `volatile` keyword, but see the limitations of this approach http://www.ibm.com/developerworks/java/library/j-dcl/index.html[here].

== Example: Singleton via MetaProgramming

Groovy's meta-programming capabilities allow concepts like the singleton pattern to be enacted in a far more fundamental way. This example illustrates a simple way to use Groovy's meta-programming capabilities to achieve the singleton pattern but not necessarily the most efficient way.

Suppose we want to keep track of the total number of calculations that a calculator performs. One way to do that is to use a singleton for the calculator class and keep a variable in the class with the count.

First we define some base classes. A `Calculator` class which performs calculations and records how many such calculations it performs and a `Client` class which acts as a facade to the calculator.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_meta_programming_classes,indent=0]
----

Now we can define and register a __MetaClass__ which intercepts all attempts to create a `Calculator` object and always provides a pre-created instance instead. We also register this MetaClass with the Groovy system:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_meta_programming_meta_class,indent=0]
----

Now we use instances of our `Client` class from within a script. The client class will attempt to create new instances of the calculator but will always get the singleton.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_meta_programming_usage,indent=0]
----

Here is the result of running this script (your hashcode values may vary):

----
Client: 7306473, Calc: 24230857, Total Calculations: 1
Client: 31436753, Calc: 24230857, Total Calculations: 2
----

== Guice Example

We can also implement the Singleton Pattern using https://github.com/google/guice[Guice].

Consider the Calculator example again.

Guice is a Java-oriented framework that supports Interface-Oriented design. Hence we create a `Calculator` interface first. We can then create our `CalculatorImpl` implementation and a `Client` object which our script will interact with. The `Client` class isn't strictly needed for this example but allows us to show that non-singleton instances are the default. Here is the code:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_guice,indent=0]
----

Note the `@Inject` annotation in the `Client` class. We can always tell right in the source code which fields will be injected.

In this example we chose to use an __explicit__ binding. All of our dependencies (ok, only one in this example at the moment) are configured in the binding. The Guide injector knows about the binding and injects the dependencies as required when we create objects. For the singleton pattern to hold, you must always use Guice to create your instances. Nothing shown so far would stop you creating another instance of the calculator manually using ++new CalculatorImpl()++ which would of course violate the desired singleton behaviour.

In other scenarios (though probably not in large systems), we could choose to express dependencies using annotations, such as the following example shows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_guice2,indent=0]
----

Note the `@Singleton` annotation on the `CalculatorImpl` class and the `@ImplementedBy` annotation in the `Calculator` interface.

When run, the above example (using either approach) yields (your hashcode values will vary):

----
Client: 8897128, Calc: 17431955, Total Calculations: 1
Client: 21145613, Calc: 17431955, Total Calculations: 2
----

You can see that we obtained a new client object whenever we asked for an instance but it was injected with the same calculator object.

== Spring Example

We can do the Calculator example again using Spring as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=singleton_spring,indent=0]
----

And here is the result (your hashcode values will vary):

----
Client: 29418586, Calc: 10580099, Total Calculations: 1
Client: 14800362, Calc: 10580099, Total Calculations: 2
----

== Further information

- http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html?page=1[Simply Singleton]
- http://www.ibm.com/developerworks/webservices/library/co-single/index.html[Use your singletons wisely]
- http://www.ibm.com/developerworks/java/library/j-dcl/index.html[Double-checked locking and the Singleton pattern]
- https://web.archive.org/web/20160807234810/http://blog.crazybob.org/2007/01/lazy-loading-singletons.html[Lazy Loading Singletons]
- https://csharpindepth.com/Articles/Singleton[Implementing the Singleton Pattern in C#]

---

### Src Spec Doc  Design Pattern State (`src/spec/doc/_design-pattern-state.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= State Pattern

The https://en.wikipedia.org/wiki/State_pattern[State Pattern] provides a structured approach to partitioning the behaviour within complex systems. The overall behaviour of a system is partitioned into well-defined states. Typically, each state is implemented by a class. The overall system behaviour can be determined firstly by knowing the __current state__ of the system; secondly, by understanding the behaviour possible while in that state (as embodied in the methods of the class corresponding to that state).

== Example

Here is an example:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_example,indent=0]
----

Here is the output:

----
offline
error: not connected
connected
"Hello" sent
error: already connected
message received
offline
----

One of the great things about a dynamic language like Groovy though is that we can take this example and express it in many different ways depending on our particular needs. Some potential variations for this example are shown below.

== Variation 1: Leveraging Interface-Oriented Design

One approach we could take is to leverage http://www.pragmaticprogrammer.com/titles/kpiod/index.html[Interface-Oriented Design]. To do this, we could introduce the following interface:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation1_interface,indent=0]
----

Then our `Client`, `Online` and 'Offline` classes could be modified to implement that interface, e.g.:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation1_impl,indent=0]
----

You might ask: Haven't we just introduced additional boilerplate code? Can't we rely on duck-typing for this? The answer is 'yes' and 'no'. We can get away with duck-typing but one of the key intentions of the state pattern is to partition complexity. If we know that the __client__ class and each __state__ class all satisfy one interface, then we have placed some key boundaries around the complexity. We can look at any state class in isolation and know the bounds of behaviour possible for that state.

We don't have to use interfaces for this, but it helps express the intent of this particular style of partitioning and it helps reduce the size of our unit tests (we would have to have additional tests in place to express this intent in languages which have less support for interface-oriented design).

== Variation 2: Extract State Pattern Logic

Alternatively, or in combination with other variations, we might decide to extract some of our State Pattern logic into helper classes. For example, we could define the following classes in a state pattern package/jar/script:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation2_classes,indent=0]
----

This is all quite generic and can be used wherever we want to introduce the state pattern. Here is what our code would look like now:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation2_impl,indent=0]
----

You can see here the `startFrom` and `transitionTo` methods begin to give our example code a DSL feel.

== Variation 3: Bring on the DSL

Alternatively, or in combination with other variations, we might decide to fully embrace a Domain Specific Language (DSL) approach to this example.

We can define the following generic helper functions (first discussed https://web.archive.org/web/20170624004445/http://www.bytemycode.com:80/snippets/snippet/640/[here]):

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation31,indent=0]
----

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation32,indent=0]
----

Now we can define and test our state machine like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=state_variation33,indent=0]
----

This example isn't an exact equivalent of the others. It doesn't use predefined `Online` and `Offline` classes.
Instead, it defines the entire state machine on the fly as needed.
See the https://web.archive.org/web/20170624004445/http://www.bytemycode.com:80/snippets/snippet/640/[previous reference] for more elaborate examples of this style.

See also: https://web.archive.org/web/20150102211229/http://groovy.codehaus.org/Model-based+testing+using+ModelJUnit[Model-based testing using ModelJUnit]

---

### Src Spec Doc  Design Pattern Strategy (`src/spec/doc/_design-pattern-strategy.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Strategy Pattern

The http://en.wikipedia.org/wiki/Strategy_pattern[Strategy Pattern] allows you to abstract away particular algorithms from their usage. This allows you to easily swap the algorithm being used without having to change the calling code. The general form of the pattern is:

[plantuml, StrategyClasses, png]
....
!pragma layout smetana
hide fields
hide <<Hidden>> circle
skinparam ClassBorderColor<<Hidden>> Transparent
skinparam ClassBackgroundColor<<Hidden>> Transparent
skinparam ClassStereotypeFontColor<<Hidden>> Transparent
skinparam ClassFontSize<<Hidden>> 24
skinparam ClassFontStyle<<Hidden>> bold
skinparam shadowing<<Hidden>> false
class Context {
    +Strategy getStrategy()
}
class Strategy {
    +algorithmMethod()
}
class ConcreteStrategy1 {
    +algorithmMethod()
}
class ConcreteStrategy2 {
    +algorithmMethod()
}
class "..." as ConcreteHidden
class ConcreteHidden <<Hidden>> {
}
class ConcreteStrategyN {
    +algorithmMethod()
}
Context o---r--- Strategy
Strategy <|-- ConcreteStrategy1
Strategy <|-- ConcreteStrategy2
Strategy <|-[hidden]- ConcreteHidden
Strategy <|-- ConcreteStrategyN
....

In Groovy, because of its ability to treat code as a first class object using anonymous methods (which we loosely call __Closures__), the need for the strategy pattern is greatly reduced. You can simply place algorithms inside Closures.

== Example using traditional class hierarchy

First let's look at the traditional way of encapsulating the Strategy Pattern.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=strategy_traditional,indent=0]
----

Here we have defined an interface `Calc` which our concrete strategy classes will implement (we could also have used an abstract class).
We then defined two algorithms for doing simple multiplication: `CalcByMult` the normal way, and ++CalcByManyAdds++ using only addition (don't try this one using negative numbers - yes we could fix this but it would just make the example longer).
We then use normal http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming[polymorphism] to invoke the algorithms.

== Example using closures

Here is the Groovier way to achieve the same thing using Closures:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=strategy_groovy_way,indent=0]
----

== Example using lambdas

For Groovy 3+, we can leverage lambda syntax:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=strategy_lambdas_with_explicit_interface,indent=0]
----

Or we can use the built-in JDK `BiFunction` class:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=strategy_lambdas_using_bifunction,indent=0]
----

---

### Src Spec Doc  Design Pattern Template Method (`src/spec/doc/_design-pattern-template-method.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Template Method Pattern


The https://en.wikipedia.org/wiki/Template_method_pattern[Template Method Pattern] abstracts
away the details of several algorithms.
The generic part of an algorithm is contained within a base class.
Particular implementation details are captured within child classes.
The generic pattern of classes involved looks like this:

[plantuml, TemplateMethodClasses, png]
....
!pragma layout smetana
skinparam nodesep 100
class AbstractClass {
    +algorithm1()
    +algorithm2()
    {abstract} +primitiveOperationA()
    {abstract} +primitiveOperationB()
}
class ConcreteClass1 {
    +primitiveOperationA()
    +primitiveOperationB()
}
class ConcreteClass2 {
    +primitiveOperationA()
    +primitiveOperationB()
}
object templateMethodUser
hide fields
templateMethodUser ......r......> "<<use>>" AbstractClass
AbstractClass <|-- ConcreteClass1
AbstractClass <|-- ConcreteClass2
....

== Example with traditional classes

In this example, the base `Accumulator` class captures the essence of the accumulation algorithm.
The child classes `Sum` and `Product` provide particular customised ways to use the generic accumulation algorithm.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=template_method_example,indent=0]
----

== Example with simplifying strategies

In this particular case, you could use Groovy's inject method to achieve a similar result using Closures:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=template_method_example2,indent=0]
----

Thanks to duck-typing, this would also work with other objects which support an add (`plus()` in Groovy) method, e.g.:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=template_method_example3,indent=0]
----

We could also do the multiplication case as follows (re-writing as a one-liner):

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=template_method_example4,indent=0]
----
Using closures this way looks like the <<_strategy_pattern,Strategy Pattern>>, but if we realise
that Groovy's `inject` method is the generic part of the algorithm for our template method,
then the Closures become the customised parts of the template method pattern.

For Groovy 3+, we can use lambda syntax as an alternative to the closure syntax:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=template_method_example5,indent=0]
----

Here the stream api's `reduce` method is the generic part of the algorithm for our template method,
and the lambdas are the customised parts of the template method pattern.

---

### Src Spec Doc  Design Pattern Visitor (`src/spec/doc/_design-pattern-visitor.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Visitor Pattern

The https://en.wikipedia.org/wiki/Visitor_pattern[Visitor Pattern] is one of those well-known but not
often used patterns. Perhaps this is because it seems a little complex at first.
But once you become familiar with it, it becomes a powerful way to evolve your code
and as we'll see, Groovy provides ways to reduce some to the complexity, so there is
no reason not to consider using this pattern.

The goal of the pattern is to separate an algorithm from an object structure.
A practical result of this separation is the ability to add new operations to existing
object structures without modifying those structures.

== Simple Example

This example considers how to calculate the bounds of shapes (or collections of shapes).
Our first attempt uses the traditional visitor pattern.
We will see a more Groovy way to do this shortly.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_simple_example,indent=0]
----

That took quite a bit of code, but the idea now is that we could add
further algorithms just by adding new visitors with our shape classes remaining
unchanged, e.g. we could add a total area visitor or a collision detection visitor.

We can improve the clarity of our code (and shrink it to about half the size) by
making use of Groovy Closures as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_simple_example2,indent=0]
----

Or, using lambdas as follows:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_simple_example3,indent=0]
----

== Advanced Example

Let's consider another example to illustrate some more points about this pattern.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_advanced_example,indent=0]
----

If we now use `NodeType1Counter` on a tree like this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_advanced_example2,indent=0]
----

Then we have one `NodeType1` object as root and one of the children is also a `NodeType1` instance.
The other child is a `NodeType2` instance.
That means using `NodeType1Counter` here should count 2 `NodeType1` objects as the last statement verifies.

=== When to use this

This example illustrates some of the advantages of the visitor pattern.
For example, while our visitor has state (the count of `NodeType1` objects), the tree of objects itself is not changed.
Similarly, if we wanted to have a visitor counting all node types,
or one that counts how many different types are used, or one that gathers information
using methods special to the node types, again, the visitor alone is all that would need to be written.

=== What happens if we add a new type?

In this case we might have a fair bit of work to do. We probably have to change the `Visitor` interface to accept the new type,
and change potentially most existing visitors based on that interface change,
and we have to write the new type itself.
A better approach is to write a default implementation of the visitor which all concrete visitors will extend.
We'll see this approach in use shortly.

=== What if we want to have different iteration patterns?

Then you have a problem.
Since the node describes how to iterate, you have no influence and stop iteration at a point or change the order.
So maybe we should change this a little to this:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_advanced_example3,indent=0]
----

Some small changes but with big effect.
The visitor is now recursive and tells me how to iterate.
The implementation in the Nodes is minimized to `visitor.visit(this)`, `DefaultVisitor` is now able to catch the new types, we can stop iteration by not delegating to super.
Of course the big disadvantage now is that it is no longer iterative, but you can't get all the benefits.

=== Make it Groovy

The question now is how to make that a bit more Groovy.
Didn't you find this `visitor.visit(this)` strange? Why is it there?
The answer is to simulate double dispatch.
In Java, the compile time type is used, so for `visitor.visit(children[i])` the compiler won't be
able to find the correct method, because `Visitor` does not contain a method `visit(Visitable)`.
And even if it would, we would like to visit the more special methods with `NodeType1` or `NodeType2`.

Now Groovy is not using the static type, Groovy uses the runtime type.
This means we can use `visitor.visit(children[i])` without any problem.
Since we minimized the accept method to just do the double dispatch part and
since the runtime type system of Groovy will already cover that, do we need the accept method?
Not really, but we can do even more.
We had the disadvantage of not knowing how to handle unknown tree elements.
We had to _extend_ the interface `Visitor` for that, resulting in changes to `DefaultVisitor` and
then we have the task to provide a useful default like iterating the node or not doing anything at all.
Now with Groovy we can catch that case by adding a `visit(Visitable)` method that does nothing.
That would be the same in Java btw.

But don't let us stop here. Do we need the `Visitor` interface?
If we don't have the accept method, then we don't need the `Visitor` interface at all.
So the new code would be:

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_advanced_example4,indent=0]
----

Looks like we saved a few lines of code here, but we made more.
The `Visitable` nodes now do not refer to any `Visitor` class or interface.
This is about the best level of separation you might expect here, but we can go further.
Let's change the `Visitable` interface a little and let it return the children we want to visit next.
This allows us a general iteration method.

[source,groovy]
----
include::../test/DesignPatternsTest.groovy[tags=visitor_advanced_example5,indent=0]
----

`DefaultVisitor` now looks a bit different.
It has a `doIteration` method that will get the children it should iterate over and then call visit on each element.
Per default this will call `visit(Visitable)` which then iterates over the children of this child.
`Visitable` has also changed to ensure that any node will be able to return children (even if empty).
We didn't have to change the `NodeType1` and `NodeType2` class, because the way the children field was
defined already made them a property, which means Groovy is so nice to generate a get method for us.
Now the really interesting part is `NodeType1Counter`, it is interesting because we have not changed it.
`super.visit(n1)` will now call `visit(Visitable)` which will call `doIteration` which will start the next level of iteration.
So no change. But `visit(it)` will call `visit(NodeType1)` if it is of type `NodeType1`.
In fact, we don't need the `doIteration` method, we could do that in `visit(Visitable)` too,
but this variant has some benefits. It allows us to write a new `Visitor` that overwrites visit(`Visitable`)
for error cases which of course means we must not do `super.visit(n1)` but `doIteration(n1)`.

=== Summary

In the end we got ~40% less code, a robust and stable architecture,
and we completely removed the Visitor from the Visitable.
To achieve the same in Java, you would probably need to resort to reflection.

The visitor pattern has sometimes been described as a poor fit for extreme programming
techniques because you need to make changes to so many classes all the time.
With our design, if we add new types we don't need to change anything.
So, the pattern is a good fit for agile approaches when using Groovy.

There are variants of the Visitor pattern, like the https://java-design-patterns.com/patterns/acyclic-visitor/[acyclic visitor pattern],
that try to solve the problem of adding new node types with special visitors.
The implementations of these visitors have their own code smells, like using casts, overuse of `instanceof`, and other tricks.
What's more the problems such approaches are trying to solve don't occur within the Groovy version. We recommend avoiding that variant of this pattern.

Finally, in case it isn't obvious, `NodeType1Counter` could be implemented in Java as well.
Groovy will recognize the visit methods and call them as needed because `DefaultVisitor` is still Groovy and does all the magic.

== Further Information

- http://se.ethz.ch/~meyer/publications/computer/visitor.pdf[Componentization: the Visitor example]

---

### Src Spec Doc  Records (`src/spec/doc/_records.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Record classes (incubating)

Record classes, or _records_ for short, are a special kind of class
useful for modelling plain data aggregates.
They provide a compact syntax with less ceremony than normal classes.
Groovy already has AST transforms such as `@Immutable` and `@Canonical`
which already dramatically reduce ceremony but records have been
introduced in Java and record classes in Groovy are designed to align
with Java record classes.

For example, suppose we want to create a `Message` record
representing an email message. For the purposes of this example,
let's simplify such a message to contain just a _from_ email address,
a _to_ email address, and a message _body_. We can define such
a record as follows:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_message_defn,indent=0]
----

We'd use the record class in the same way as a normal class, as shown below:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_message_usage,indent=0]
----

The reduced ceremony saves us from defining explicit fields, getters and
`toString`, `equals` and `hashCode` methods. In fact, it's a shorthand
for the following rough equivalent:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_message_equivalent,indent=0]
----

Note the special naming convention for record getters. They are the same name as the field
(rather than the often common JavaBean convention of capitalized with a "get" prefix).
Rather than referring to a record's fields or properties, the term _component_
is typically used for records. So our `Message` record has `from`, `to`, and `body` components.

Like in Java, you can override the normally implicitly supplied methods
by writing your own:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point3d,indent=0]
----

You can also use generics with records in the normal way. For example, consider the following `Coord` record definition:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_generics_defn,indent=0]
----

It can be used as follows:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_generics_usage,indent=0]
----

== Special record features

=== Compact constructor

Records have an implicit constructor. This can be overridden in the normal way
by providing your own constructor - you need to make sure you set all the fields
if you do this.
However, for succinctness, a compact constructor syntax can be used where
the parameter declaration part of a normal constructor is elided.
For this special case, the normal implicit constructor is still provided
but is augmented by the supplied statements in the compact constructor definition:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_compact_constructor,indent=0]
----

=== Serializability

Groovy _native_ records follow the
https://docs.oracle.com/en/java/javase/16/docs/specs/records-serialization.html[special conventions]
for serializability which apply to Java records.
Groovy _record-like_ classes (discussed below) follow normal Java class serializability conventions.

== Groovy enhancements

=== Argument defaults

Groovy supports default values for constructor arguments.
This capability is also available for records as shown in the following record definition
which has default values for `y` and `color`:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point_defn,indent=0]
----

Arguments when left off (dropping one or more arguments from the right) are replaced
with their defaults values as shown in the following example:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point_defaults,indent=0]
----

This processing follows normal Groovy conventions for default arguments for constructors, essentially automatically providing the constructors with the following signatures:

[source,groovy]
----
ColoredPoint(int, int, String)
ColoredPoint(int, int)
ColoredPoint(int)
----

Named arguments may also be used (default values also apply here):

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point_named_args,indent=0]
----

You can disable default argument processing as shown here:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point_named_args_off,indent=0]
----

This will produce a single constructor as per the default with Java.
It will be an error if you drop off arguments in this scenario.

You can force all properties to have a default value as shown here:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point_named_args_on,indent=0]
----

Any property/field without an explicit initial value will be given the default value for the argument's type (null, or zero/false for primitives).

.Diving deeper
****
We previously described a `Message` record and displayed it's rough equivalent.
Groovy in fact steps through an intermediate stage where the `record` keyword
is replaced by the `class` keyword and an accompanying `@RecordType` annotation:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_message_annotation_defn,indent=0]
----

Then `@RecordType` itself is processed as a _meta-annotation_ (annotation collector)
and expanded into its constituent sub-annotations such as `@TupleConstructor`, `@POJO`,
`@RecordBase`, and others. This is in some sense an implementation detail which can often be ignored.
However, if you wish to customise or configure the record implementation,
you may wish to drop back to the `@RecordType` style or augment your record class
with one of the constituent sub-annotations.
****

=== Declarative `toString` customization

As per Java, you can customize a record's `toString` method by writing your own.
If you prefer a more declarative style, you can alternatively use Groovy's `@ToString` transform
to override the default record `toString`.
As an example, you can a three-dimensional point record as follows:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point3d_tostring_annotation,indent=0]
----

We customise the `toString` by including the package name (excluded by default for records)
and by caching the `toString` value since it won't change for this immutable record.
We are also ignoring null values (the default value for `z` in our definition).

We can have a similar definition for a two-dimensional point:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_point2d_tostring_annotation,indent=0]
----

We can see here that without the package name it would have the same toString as our previous example.

=== Obtaining a list of the record component values

We can obtain the component values from a record as a list like so:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_to_list,indent=0]
----

You can use `@RecordOptions(toList=false)` to disable this feature.

=== Obtaining a map of the record component values

We can obtain the component values from a record as a map like so:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_to_map,indent=0]
----

You can use `@RecordOptions(toMap=false)` to disable this feature.

=== Obtaining the number of components in a record

We can obtain the number of components in a record like so:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_size,indent=0]
----

You can use `@RecordOptions(size=false)` to disable this feature.

=== Obtaining the n^th^ component from a record

We can use Groovy's normal positional indexing to obtain a particular component in a record like so:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_get_at,indent=0]
----

You can use `@RecordOptions(getAt=false)` to disable this feature.

== Optional Groovy features

=== Copying

It can be useful to make a copy of a record with some components changed.
This can be done using an optional `copyWith` method which takes named arguments.
Record components are set from the supplied arguments.
For components not mentioned, a (shallow) copy of the original record component is used.
Here is how you might use `copyWith` for the `Fruit` record:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_copywith,indent=0]
----

The `copyWith` functionality can be disabled by setting the
`RecordOptions#copyWith` annotation attribute to `false`.

=== Deep immutability

As with Java, records by default offer shallow immutability.
Groovy's `@Immutable` transform performs defensive copying for a range of mutable
data types. Records can make use of this defensive copying to gain deep immutability as follows:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_immutable,indent=0]
----

These examples illustrate the principal behind
Groovy's record feature offering three levels of convenience:

* Using the `record` keyword for maximum succinctness
* Supporting low-ceremony customization using declarative annotations
* Allowing normal method implementations when full control is required

===  Obtaining the components of a record as a typed tuple

You can obtain the components of a record as a typed tuple:

[source,groovy]
----
include::../test/RecordSpecificationTest.groovy[tags=record_components,indent=0]
----

Groovy has a limited number of `TupleN` classes.
If you have a large number of components in your record, you might not be able to use this feature.

== Other differences to Java

Groovy supports creating _record-like_ classes as well as native records.
Record-like classes don't extend Java's `Record` class and such classes
won't be seen by Java as records but will otherwise have similar properties.

The `@RecordOptions` annotation (part of `@RecordType`) supports a `mode` annotation attribute
which can take one of three values (with `AUTO` being the default):

NATIVE::
Produces a class similar to what Java would do.
EMULATE::
Produces a record-like class.
AUTO::
Equivalent to `NATIVE` at Groovy 6's JDK17+ baseline (default).

Whether you use the `record` keyword or the `@RecordType` annotation
is independent of the mode.

---

### Src Spec Doc  Sealed (`src/spec/doc/_sealed.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Sealed hierarchies

Sealed classes, interfaces and traits restrict which subclasses can extend/implement them.
Prior to sealed classes, class hierarchy designers had two main options:

* Make a class final to allow no extension.
* Make the class public and non-final to allow extension by anyone.

Sealed classes provide a middle-ground compared to these all or nothing choices.

Sealed classes are also more flexible than other tricks previously used
to try to achieve a middle-ground. For example, for class hierarchies,
access modifiers like protected and package-private give some ability to restrict inheritance
hierarchies but often at the expense of flexible use of those hierarchies.

Sealed hierarchies provide full inheritance within a known hierarchy of classes, interfaces
and traits but disable or only provide controlled inheritance outside the hierarchy.

As an example, suppose we want to create a shape hierarchy containing
only circles and squares. We also want a shape interface to
be able to refer to instances in our hierarchy.
We can create the hierarchy as follows:

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=simple_interface_keyword,indent=0]
----

Groovy also supports an alternative annotation syntax.
We think the keyword style is nicer but you might choose the annotation style if your editor doesn't yet have Groovy 4 support.

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=simple_interface_annotations,indent=0]
----

We can have a reference of type `ShapeI` which, thanks to the `permits` clause,
can point to either a `Circle` or `Square` and, since our classes are `final`,
we know no additional classes will be added to our hierarchy in the future.
At least not without changing the `permits` clause and recompiling.

In general, we might want to have some parts of our class hierarchy
immediately locked down like we have here, where we marked the
subclasses as `final` but other times we might want to allow further
controlled inheritance.

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=general_sealed_class,indent=0]
----

.<Click to see the alternate annotations syntax>
[%collapsible]
====
[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=general_sealed_class_annotations,indent=0]
----
====

&nbsp; +
In this example, our permitted subclasses for `Shape` are `Circle`, `Polygon`, and `Rectangle`.
`Circle` is `final` and hence that part of the hierarchy cannot be extended.
`Polygon` is implicitly non-sealed and `RegularPolygon` is explicitly marked as `non-sealed`.
That means our hierarchy is open to any further extension by subclassing,
as seen with `Polygon -> RegularPolygon` and `RegularPolygon -> Hexagon`.
`Rectangle` is itself sealed which means that part of the hierarchy can be extended
but only in a controlled way (only `Square` is permitted).

Sealed classes are useful for creating enum-like related classes
which need to contain instance specific data. For instance, we might have the following enum:

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=weather_enum,indent=0]
----

but we now wish to also add weather specific instance data to weather forecasts.
We can alter our abstraction as follows:

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=weather_sealed,indent=0]
----

Sealed hierarchies are also useful when specifying Algebraic or Abstract Data Types (ADTs) as shown in the following example:

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=sealed_ADT,indent=0]
----

Sealed hierarchies work well with records as shown in the following example:

[source,groovy]
----
include::../test/SealedSpecificationTest.groovy[tags=sealedRecord_ADT,indent=0]
----

== Differences to Java

* Java provides no default modifier for subclasses of sealed classes
and requires that one of `final`, `sealed` or `non-sealed` be specified.
Groovy defaults to _non-sealed_ but you can still use `non-sealed/@NonSealed` if you wish.
We anticipate the style checking tool CodeNarc will eventually have a rule that
looks for the presence of `non-sealed` so developers wanting that stricter
style will be able to use CodeNarc and that rule if they want.

* Currently, Groovy doesn't check that all classes mentioned in `permittedSubclasses`
are available at compile-time and compiled along with the base sealed class.
This may change in a future version of Groovy.

Groovy supports annotating classes as sealed as well as "native" sealed classes.

The `@SealedOptions` annotation supports a `mode` annotation attribute
which can take one of three values (with `AUTO` being the default):

NATIVE::
Produces a class similar to what Java would do.
Produces an error when compiling on JDKs earlier than JDK17.
EMULATE::
Indicates the class is sealed using the `@Sealed` annotation.
This mechanism works with the Groovy compiler for JDK8+ but is not recognised by the Java compiler.
AUTO::
Produces a native sealed class for JDK17+ and emulates the sealed nature otherwise.

Whether you use the `sealed` keyword or the `@Sealed` annotation
is independent of the mode.

---

### Src Spec Doc  Traits (`src/spec/doc/_traits.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Traits

Traits are a structural construct of the language which allows:

* composition of behaviors
* runtime implementation of interfaces
* behavior overriding
* compatibility with static type checking/compilation

They can be seen as *interfaces* carrying both *default implementations* and *state*. A trait is defined using the
`trait` keyword:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
----
<1> declaration of a trait
<2> declaration of a method inside a trait

Then it can be used like a normal interface using the `implements` keyword:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=bird,indent=0]
----
<1> Adds the trait `FlyingAbility` to the `Bird` class capabilities
<2> instantiate a new `Bird`
<3> the `Bird` class automatically gets the behavior of the `FlyingAbility` trait

Traits allow a wide range of capabilities, from simple composition to testing, which are described thoroughly in this section.

== Methods
=== Public methods

Declaring a method in a trait can be done like any regular method in a class:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
----
<1> declaration of a trait
<2> declaration of a method inside a trait

=== Abstract methods

In addition, traits may declare _abstract_ methods too, which therefore need to be implemented in the class implementing the trait:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=greetable,indent=0]
----
<1> implementing class will have to declare the `name` method
<2> can be mixed with a concrete method

Then the trait can be used like this:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=greetable_person,indent=0]
----
<1> implement the trait `Greetable`
<2> since `name` was abstract, it is required to implement it
<3> then `greeting` can be called

=== Private methods

Traits may also define private methods. Those methods will not appear in the trait contract interface:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=private_method_in_trait,indent=0]
----
<1> define a private method `greetingMessage` in the trait
<2> the public `greet` message calls `greetingMessage` by default
<3> create a class implementing the trait
<4> `greet` can be called
<5> but not `greetingMessage`

WARNING: Traits only support `public` and `private` methods. Neither `protected` nor `package private` scopes are
supported.

=== Final methods

If we have a class implementing a trait, conceptually implementations from the trait methods
are "inherited" into the class. But, in reality, there is no base class containing such
implementations. Rather, they are woven directly into the class. A final modifier on a method
just indicates what the modifier will be for the woven method. While it would likely be
considered bad style to inherit and override or multiply inherit methods with the same
signature but a mix of final and non-final variants, Groovy doesn't prohibit this scenario.
Normal method selection applies and the modifier used will be determined from the resulting method.
You might consider creating a base class which implements the desired trait(s) if you
want trait implementation methods that can't be overridden.

== The meaning of this

`this` represents the implementing instance. Think of a trait as a superclass. This means that when you write:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=meaningofthis_header,indent=0]
----

then calling:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=meaningofthis_snippet,indent=0]
----

will return the same instance:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=meaningofthis_assert,indent=0]
----

== Interfaces

Traits may implement interfaces, in which case the interfaces are declared using the `implements` keyword:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=trait_implementing_interface,indent=0]
----
<1> declaration of a normal interface
<2> add `Named` to the list of implemented interfaces
<3> declare a class that implements the `Greetable` trait
<4> implement the missing `name` method
<5> the `greeting` implementation comes from the trait
<6> make sure `Person` implements the `Named` interface
<7> make sure `Person` implements the `Greetable` trait

== Properties

A trait may define properties, like in the following example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=trait_with_property,indent=0]
----
<1> declare a property `name` inside a trait
<2> declare a class which implements the trait
<3> the property is automatically made visible
<4> it can be accessed using the regular property accessor
<5> or using the regular getter syntax

== Fields
=== Private fields

Since traits allow the use of private methods, it can also be interesting to use private fields to store state. Traits
will let you do that:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=trait_with_private_field,indent=0]
----
<1> declare a private field `count` inside a trait
<2> declare a public method `count` that increments the counter and returns it
<3> declare a class that implements the `Counter` trait
<4> the `count` method can use the private field to keep state

TIP: This is a major difference with http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html[Java 8 virtual extension methods]. While virtual extension methods
do not carry state, traits can. Moreover, traits in Groovy are supported starting with Java 6, because their implementation does not rely on virtual extension methods. This
means that even if a trait can be seen from a Java class as a regular interface, that interface will *not* have default methods, only abstract ones.

=== Public fields

Public fields work the same way as private fields, but in order to avoid the http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem[diamond problem],
field names are remapped in the implementing class:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=trait_with_public_field,indent=0]
----
<1> declare a public *field* inside the trait
<2> declare a class implementing the trait
<3> create an instance of that class
<4> the public field is available, but renamed

The name of the field depends on the fully qualified name of the trait. All dots (`.`) in package are replaced with an underscore (`_`), and the final name includes a double underscore.
So if the type of the field is `String`, the name of the package is `my.package`, the name of the trait is `Foo` and the name of the field is `bar`,
in the implementing class, the public field will appear as:

[source,groovy]
----
String my_package_Foo__bar
----

WARNING: While traits support public fields, it is not recommended to use them and considered as a bad practice.

== Composition of behaviors

Traits can be used to implement multiple inheritance in a controlled way. For example, we can have the following traits:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
include::../test/TraitsSpecificationTest.groovy[tags=speaking_simple,indent=0]
----

And a class implementing both traits:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=speakingduck,indent=0]
----
<1> the `Duck` class implements both `FlyingAbility` and `SpeakingAbility`
<2> creates a new instance of `Duck`
<3> we can call the method `fly` from `FlyingAbility`
<4> but also the method `speak` from `SpeakingAbility`

Traits encourage the reuse of capabilities among objects, and the creation of new classes by the composition of existing behavior.

== Overriding default methods

Traits provide default implementations for methods, but it is possible to override them in the implementing class. For example, we
can slightly change the example above, by having a duck which quacks:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=quackingduck,indent=0]
----
<1> define a method specific to `Duck`, named `quack`
<2> override the default implementation of `speak` so that we use `quack` instead
<3> the duck is still flying, from the default implementation
<4> `quack` comes from the `Duck` class
<5> `speak` no longer uses the default implementation from `SpeakingAbility`

== Extending traits
=== Simple inheritance
Traits may extend another trait, in which case you must use the `extends` keyword:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=trait_inherit,indent=0]
-----
<1> the `Named` trait defines a single `name` property
<2> the `Polite` trait *extends* the `Named` trait
<3> `Polite` adds a new method which has access to the `name` property of the super-trait
<4> the `name` property is visible from the `Person` class implementing `Polite`
<5> as is the `introduce` method

=== Multiple inheritance

Alternatively, a trait may extend multiple traits. In that case, all super traits must be declared in the `implements`
clause:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=trait_multiple_inherit,indent=0]
----
<1> `WithId` trait defines the `id` property
<2> `WithName` trait defines the `name` property
<3> `Identified` is a trait which inherits both `WithId` and `WithName`

== Duck typing and traits
=== Dynamic code
Traits can call any dynamic code, like a normal Groovy class. This means that you can, in the body of a method, call
methods which are supposed to exist in an implementing class, without having to explicitly declare them in an interface.
This means that traits are fully compatible with duck typing:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=ducktyping,indent=0]
----
<1> the `SpeakingDuck` expects the `quack` method to be defined
<2> the `Duck` class does implement the method using _methodMissing_
<3> calling the `speak` method triggers a call to `quack` which is handled by `methodMissing`

=== Dynamic methods in a trait

It is also possible for a trait to implement MOP methods like `methodMissing` or `propertyMissing`, in which case implementing classes
will inherit the behavior from the trait, like in this example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=dynamicobject,indent=0]
----
<1> create a trait implementing several MOP methods
<2> the `Dynamic` class defines a property
<3> the `Dynamic` class defines a method
<4> calling an existing property will call the method from `Dynamic`
<5> calling a non-existing property will call the method from the trait
<6> will call `setProperty` defined on the trait
<7> will call `getProperty` defined on the trait
<8> calling an existing method on `Dynamic`
<9> but calling a non-existing method thanks to the trait `methodMissing`

== Multiple inheritance conflicts
=== Default conflict resolution

It is possible for a class to implement multiple traits. If some trait defines a method with the same signature as a
method in another trait, we have a conflict:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=multiple_inherit_default,indent=0]
-----
<1> trait `A` defines a method named `exec` returning a `String`
<2> trait `B` defines the very same method
<3> class `C` implements both traits

In this case, the default behavior is that the method from the *last declared trait* in the `implements` clause wins.
Here, `B` is declared after `A` so the method from `B` will be picked up:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=multiple_inherit_default_assert,indent=0]
----

=== User conflict resolution

In case this behavior is not the one you want, you can explicitly choose which method to call using the `Trait.super.foo` syntax.
In the example above, we can ensure the method from trait A is invoked by writing this:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=multiple_inherit_user,indent=0]
----
<1> explicit call of `exec` from the trait `A`
<2> calls the version from `A` instead of using the default resolution, which would be the one from `B`

== Runtime implementation of traits
=== Implementing a trait at runtime
Groovy also supports implementing traits dynamically at runtime. It allows you to "decorate" an existing object using a
trait. As an example, let's start with this trait and the following class:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=runtime_header,indent=0]
----
<1> the `Extra` trait defines an `extra` method
<2> the `Something` class does *not* implement the `Extra` trait
<3> `Something` only defines a method `doSomething`

Then if we do:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=runtime_fail,indent=0]
----

the call to extra would fail because `Something` is not implementing `Extra`. It is possible to do it at runtime with
the following syntax:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=runtime_success,indent=0]
----
<1> use of the *as* keyword to coerce an object to a trait *at runtime*
<2> then `extra` can be called on the object
<3> and `doSomething` is still callable

IMPORTANT: When coercing an object to a trait, the result of the operation is not the same instance. It is guaranteed
that the coerced object will implement both the trait *and* the interfaces that the original object implements, but
the result will *not* be an instance of the original class.

=== Implementing multiple traits at once

Should you need to implement several traits at once, you can use the `withTraits` method instead of the `as` keyword:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=withtraits_header,indent=0]
include::../test/TraitsSpecificationTest.groovy[tags=withtraits_fail,indent=0]
include::../test/TraitsSpecificationTest.groovy[tags=withtraits_success,indent=0]
----
<1> call to `methodFromA` will fail because `C` doesn't implement `A`
<2> call to `methodFromB` will fail because `C` doesn't implement `B`
<3> `withTraits` will wrap `c` into something which implements `A` and `B`
<4> `methodFromA` will now pass because `d` implements `A`
<5> `methodFromB` will now pass because `d` also implements `B`

IMPORTANT: When coercing an object to multiple traits, the result of the operation is not the same instance. It is guaranteed
that the coerced object will implement both the traits *and* the interfaces that the original object implements, but
the result will *not* be an instance of the original class.

== Chaining behavior

Groovy supports the concept of _stackable traits_. The idea is to delegate from one trait to the other if the current trait
is not capable of handling a message. To illustrate this, let's imagine a message handler interface like this:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=messagehandler,indent=0]
-----

Then you can compose a message handler by applying small behaviors. For example, let's define a default handler in the
form of a trait:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=defaulthandler,indent=0]
-----

Then any class can inherit the behavior of the default handler by implementing the trait:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=simplehandler,indent=0]
-----

Now what if you want to log all messages, in addition to the default handler? One option is to write this:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=simplehandlerwithlogging,indent=0]
-----
<1> explicitly implement the `on` method
<2> perform logging
<3> continue by delegating to the `DefaultHandler` trait

This works but this approach has drawbacks:

. the logging logic is bound to a "concrete" handler
. we have an explicit reference to `DefaultHandler` in the `on` method, meaning that if we happen to change the trait that our class implements, code will be broken

As an alternative, we can write another trait which responsibility is limited to logging:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=logginghandler,indent=0]
-----
<1> the logging handler is itself a handler
<2> prints the message it receives
<3> then `super` makes it delegate the call to the next trait in the chain

Then our class can be rewritten as this:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=handlerwithlogger,indent=0]
include::../test/TraitsSpecificationTest.groovy[tags=handlerwithlogger_assert,indent=0]
-----

which will print:

----
include::../test/TraitsSpecificationTest.groovy[tags=handlerwithlogger_assert_output,indent=0]
----

As the priority rules imply that `LoggerHandler` wins because it is declared last, then a call to `on` will use
the implementation from `LoggingHandler`. But the latter has a call to `super`, which means the next trait in the
chain. Here, the next trait is `DefaultHandler` so *both* will be called:

The interest of this approach becomes more evident if we add a third handler, which is responsible for handling messages
that start with `say`:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=sayhandler,indent=0]
-----
<1> a handler specific precondition
<2> if the precondition is not met, pass the message to the next handler in the chain

Then our final handler looks like this:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=implementinghandler,indent=0]
include::../test/TraitsSpecificationTest.groovy[tags=implementinghandler_assert,indent=0]
-----

Which means:

* messages will first go through the logging handler
* the logging handler calls `super` which will delegate to the next handler, which is the `SayHandler`
* if the message starts with `say`, then the handler consumes the message
* if not, the `say` handler delegates to the next handler in the chain

This approach is very powerful because it allows you to write handlers that do not know each other and yet let you
combine them in the order you want. For example, if we execute the code, it will print:

----
include::../test/TraitsSpecificationTest.groovy[tags=implementinghandler_output,indent=0]
----

but if we move the logging handler to be the second one in the chain, the output is different:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=alternatehandler,indent=0]
include::../test/TraitsSpecificationTest.groovy[tags=alternatehandler_assert,indent=0]
----

prints:

----
include::../test/TraitsSpecificationTest.groovy[tags=alternatehandler_output,indent=0]
----

The reason is that now, since the `SayHandler` consumes the message without calling `super`, the logging handler is
not called anymore.

=== Semantics of super inside a trait

If a class implements multiple traits and a call to an unqualified `super` is found, then:

. if the class implements another trait, the call delegates to the next trait in the chain
. if there isn't any trait left in the chain, `super` refers to the super class of the implementing class (_this_)

For example, it is possible to decorate final classes thanks to this behavior:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=decoratefinalclass,indent=0]
----
<1> define a trait named `Filtering`, supposed to be applied on a `StringBuilder` at runtime
<2> redefine the `append` method
<3> remove all 'o's from the string
<4> then delegate to `super`
<5> in case `toString` is called, delegate to `super.toString`
<6> runtime implementation of the `Filtering` trait on a `StringBuilder` instance
<7> the string which has been appended no longer contains the letter `o`

In this example, when `super.append` is encountered, there is no other trait implemented by the target object, so the
method which is called is the original `append` method, that is to say the one from `StringBuilder`. The same trick
is used for `toString`, so that the string representation of the proxy object which is generated delegates to the
`toString` of the `StringBuilder` instance.

== Advanced features
=== SAM type coercion

If a trait defines a single abstract method, it is candidate for SAM (Single Abstract Method) type coercion. For example,
imagine the following trait:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=sam_trait,indent=0]
----
<1> the `greet` method is not abstract and calls the abstract method `getName`
<2> `getName` is an abstract method

Since `getName` is the _single abstract method_ in the `Greeter` trait, you can write:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=sam_trait_assignment,indent=0]
----
<1> the closure "becomes" the implementation of the `getName` single abstract method

or even:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=sam_trait_method,indent=0]
----
<1> the greet method accepts the SAM type Greeter as parameter
<2> we can call it directly with a closure

=== Differences with Java 8 default methods

In Java 8, interfaces can have default implementations of methods. If a class implements an interface and does not provide
an implementation for a default method, then the implementation from the interface is chosen. Traits behave the same but
with a major difference: the implementation from the trait is *always* used if the class declares the trait in its interface
list *and* that it doesn't provide an implementation *even* if a super class does.

This feature can be used to compose behaviors in a very precise way, in case you want to override the behavior of an
already implemented method.

To illustrate the concept, let's start with this simple example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=forceoverride_header,indent=0]
----

In this example, we create a simple test case which uses two properties (_config_ and _shell_) and uses those in
multiple test methods. Now imagine that you want to test the same, but with another distinct compiler configuration.
One option is to create a subclass of `SomeTest`:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=forceoverride_extends,indent=0]
----

It works, but what if you have actually multiple test classes, and that you want to test the new configuration for all
those test classes? Then you would have to create a distinct subclass for each test class:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=forceoverride_extends2,indent=0]
----

Then what you see is that the `setup` method of both tests is the same. The idea, then, is to create a trait:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=forceoverride_trait,indent=0]
----

Then use it in the subclasses:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=forceoverride_miss_header,indent=0]
...
----

It would allow us to dramatically reduce the boilerplate code, and reduces the risk of forgetting to change the setup
code in case we decide to change it. Even if `setup` is already implemented in the super class, since the test class declares
the trait in its interface list, the behavior will be borrowed from the trait implementation!

This feature is in particular useful when you don't have access to the super class source code. It can be used to
mock methods or force a particular implementation of a method in a subclass. It lets you refactor your code to keep
the overridden logic in a single trait and inherit a new behavior just by implementing it. The alternative, of course,
is to override the method in *every* place you would have used the new code.


IMPORTANT: It's worth noting that if you use runtime traits, the methods from the trait are *always* preferred to those of the proxied
object:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=runtime_forceoverride,indent=0]
----
<1> the `Person` class defines a `name` property which results in a `getName` method
<2> `Bob` is a trait which defines `getName` as returning `Bob`
<3> the default object will return _Alice_
<4> `p2` coerces `p` into `Bob` at runtime
<5> `getName` returns _Bob_ because `getName` is taken from the *trait*

IMPORTANT: Again, don't forget that dynamic trait coercion returns a distinct object which only implements the original
interfaces, as well as the traits.

== Differences with mixins

There are several conceptual differences with mixins, as they are available in Groovy. Note that we are talking about
runtime mixins, not the @Mixin annotation which is deprecated in favour of traits.

First of all, methods defined in a trait are visible in bytecode:

* internally, the trait is represented as an interface (without default methods; public static methods are exposed as JVM-native interface statics) and several helper classes
* this means that an object implementing a trait effectively implements an _interface_
* those methods are visible from Java
* they are compatible with type checking and static compilation

Methods added through a mixin are, on the contrary, only visible at runtime:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=diff_mixin,indent=0]
----
<1> class `A` defines `methodFromA`
<2> class `B` defines `methodFromB`
<3> mixin B into A
<4> we can call `methodFromA`
<5> we can also call `methodFromB`
<6> the object is an instance of `A`
<7> but it's *not* an instanceof `B`

The last point is actually a very important and illustrates a place where mixins have an advantage over traits: the instances
are *not* modified, so if you mixin some class into another, there isn't a third class generated, and methods which respond to
A will continue responding to A even if mixed in.

== Static methods, properties and fields

NOTE: Static member support in traits is *incubating*: the behaviour described here is settled for {groovyVersion}
but may still be refined. GEP-22 gives the full specification.

A trait may declare static methods, properties and fields:

* The trait is interpreted as a _template_ for the implementing class: each implementing class gets its *own copy*
of the trait's static members. A static member declared on a trait belongs to the implementing class, not to a
single copy shared across all implementers.
* Public static methods are _declarer-bound_ by default and are promoted onto the generated trait interface as
JVM-native static methods, so both `Trait.m(...)` and `Impl.m(...)` resolve. A private static method stays internal
to the trait and is not promoted.
* Static methods may be declared in, and called from, `@CompileStatic` and `@TypeChecked` code; they are not
restricted to dynamic Groovy.
* You should typically not mix static and instance methods of the same signature. The normal trait method-selection
rules apply (including multiple inheritance conflict resolution): if the selected method is static but some
implemented trait has an instance variant, a compilation error occurs; if the instance variant is selected, the
static variant is ignored (as with static methods in Java interfaces for this case).

Let's start with a simple example:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=staticfield_header,indent=0]
-----
<1> the static field is declared in the trait
<2> a static method is also declared in the trait
<3> the static field is updated _within_ the trait
<4> a static method _init_ is made available to the implementing class
<5> the static field is _remapped_ to avoid the diamond issue

As usual, it is not recommended to use public fields. Anyway, should you want this, you must understand that the following code would fail:

[source,groovy]
-----
include::../test/TraitsSpecificationTest.groovy[tags=staticfield_notontrait,indent=0]
-----

because there is _no_ static field _CALLED_ defined on the trait itself. Likewise, if you have two distinct implementing classes, each one gets a distinct static field:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=staticfield_distinct,indent=0]
----
<1> class `Bar` implements the trait
<2> class `Baz` also implements the trait
<3> `init` is only called on `Bar`
<4> the static field `CALLED` on `Bar` is updated
<5> but the static field `CALLED` on `Baz` is not, because it is *distinct*

=== Overridable static defaults with `@Virtual`

By default a trait's static method is _declarer-bound_: when other trait code calls it, it always resolves to the
trait's own copy, even if an implementing class declares a static method of the same signature. That is the right
choice for an internal helper or a constant that the trait owns outright.

Sometimes, though, a trait wants to publish a static *default that an implementing class can override*, and have
the trait's own logic honour that override. This is the template-method pattern applied to a static member — the
same override-visibility that trait _instance_ methods already have. Annotate the method with
`@groovy.transform.Virtual` to opt into per-implementer override dispatch:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=virtual_default,indent=0]
----
<1> the overridable default, marked `@Virtual`
<2> trait logic that consults the setting
<3> an unqualified call, so it dispatches through the implementing class
<4> uses the trait's default
<5> overrides the default with its own `static`
<6> the default is seen for `StrictEntity`
<7> the override is seen by the trait's own `describe()` for `LenientEntity`
<8> and externally via `Impl.m()`

Reach for `@Virtual` when the overridable thing is genuinely a property of the _type_ rather than of an instance —
a policy or configuration default that answers a question about the class as a whole (Grails uses this for hooks
such as `Validateable.defaultNullable()`), that may be consulted where no instance exists yet (class
initialisation, static factory methods, building metadata), and that external callers can read statically as
`Impl.setting()`. For overridable static _data_ rather than behaviour, use a `@Virtual` accessor
(`@Virtual static getSetting()`) rather than a static field, since a bare static-field read from trait code is not
override-visible (see <<_inheritance_of_state_gotchas,Inheritance of state gotchas>>).

A `@Virtual` static is deliberately *not* exposed on the trait interface (interface statics are declarer-bound by
JVM rule, which is incompatible with override dispatch). It therefore has no qualified `Trait.m(...)` form: read a
concrete class's value with `Impl.m(...)`, or use `T.super.m(...)` from within trait code for the trait's own
default. A qualified `Trait.m(...)` call to a `@Virtual` static is rejected at compile time:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=virtual_qualified,indent=0]
----
<1> rejected: a `@Virtual` static has no qualified `Trait.m(...)` form

== Inheritance of state gotchas

We have seen that traits are stateful. It is possible for a trait to define fields or properties, but when a class implements a trait, it gets those fields/properties on
a per-trait basis. So consider the following example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=intcouple,indent=0]
----


The trait defines two properties, `x` and `y`, as well as a `sum` method. Now let's create a class which implements the trait:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=intcouple_impl,indent=0]
----

The result of calling `f` is `3`, because `f` delegates to `sum` in the trait, which has state. But what if we write this instead?

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override,indent=0]
----
<1> Override property `x`
<2> Override property `y`
<3> Call `sum` from trait

If you call `elem.f()`, what is the expected output? Actually it is:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override_assert,indent=0]
----

The reason is that the `sum` method accesses the _fields_ of the trait. So it is using the `x` and `y` values defined
in the trait. If you want to use the values from the implementing class, then you need to dereference fields by using
getters and setters, like in this last example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override_directgetter,indent=0]
----

== Self types
=== Type constraints on traits

Sometimes you will want to write a trait that can only be applied to some type. For example, you may want to apply a
trait on a class that extends another class which is beyond your control, and still be able to call those methods.
To illustrate this, let's start with this example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=selftype_intro,indent=0]
----
<1> A `Service` class, beyond your control (in a library, ...) defines a `sendMessage` method
<2> A `Device` class, beyond your control (in a library, ...)
<3> Defines a communicating trait for devices that can call the service
<4> Defines `MyDevice` as a communicating device
<5> The method from the trait is called, and `id` is resolved

It is clear, here, that the `Communicating` trait can only apply to `Device`. However, there's no explicit
contract to indicate that, because traits cannot extend classes. However, the code compiles and runs perfectly
fine, because `id` in the trait method will be resolved dynamically. The problem is that there is nothing that
prevents the trait from being applied to any class which is *not* a `Device`. Any class which has an `id` would
work, while any class that does not have an `id` property would cause a runtime error.

The problem is even more complex if you want to enable type checking or apply `@CompileStatic` on the trait: because
the trait knows nothing about itself being a `Device`, the type checker will complain saying that it does not find
the `id` property.

One possibility is to explicitly add a `getId` method in the trait, but it would not solve all issues. What if a method
requires `this` as a parameter, and actually requires it to be a `Device`?

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=selftype_securityservice,indent=0]
----

If you want to be able to call `this` in the trait, then you will explicitly need to cast `this` into a `Device`. This can
quickly become unreadable with explicit casts to `this` everywhere.

[[traits-selftype]]
=== The @SelfType annotation

In order to make this contract explicit, and to make the type checker aware of the _type of itself_, Groovy provides
a `@SelfType` annotation that will:

* let you declare the types that a class that implements this trait must inherit or implement
* throw a compile-time error if those type constraints are not satisfied

So in our previous example, we can fix the trait using the `@groovy.transform.SelfType` annotation:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=selftype_fixed,indent=0]
----

Now if you try to implement this trait on a class that is *not* a device, a compile-time error will occur:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=selftype_compiletimeerror,indent=0]
----

The error will be:

----
class 'MyDevice' implements trait 'Communicating' but does not extend self type class 'Device'
----

In conclusion, self types are a powerful way of declaring constraints on traits without having to declare the contract
directly in the trait or having to use casts everywhere, maintaining separation of concerns as tight as it should be.

=== Differences with Sealed annotation (incubating)

Both `@Sealed` and `@SelfType` restrict classes which use a trait but in orthogonal ways.
Consider the following example:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=selftype_sealed_volume,indent=0]
----
<1> All usages of the `HasVolume` trait must implement or extend both `HasHeight` and `HasArea`
<2> Only `UnitCube` or `UnitCylinder` can use the trait

For the degenerate case where a single class implements a trait, e.g.:

[source,groovy]
----
final class Foo implements FooTrait {}
----

Then, either:

[source,groovy]
----
@SelfType(Foo)
trait FooTrait {}
----

or:

[source,groovy]
----
@Sealed(permittedSubclasses='Foo') // <1>
trait FooTrait {}
----
<1> Or just `@Sealed` if `Foo` and `FooTrait` are in the same source file

could express this constraint. Generally, the former of these is preferred.

== Limitations
=== Compatibility with AST transformations

CAUTION: Traits are not officially compatible with AST transformations. Some of them, like `@CompileStatic` will be applied
on the trait itself (not on implementing classes), while others will apply on both the implementing class and the trait.
There is absolutely no guarantee that an AST transformation will run on a trait as it does on a regular class, so use it
at your own risk!

=== Prefix and postfix operations

Within traits, prefix and postfix operations are not allowed if they update a field of the trait:

[source,groovy]
----
include::../test/TraitsSpecificationTest.groovy[tags=prefix_postfix,indent=0]
----
<1> `x` is defined within the trait, postfix increment is not allowed
<2> `x` is defined within the trait, prefix decrement is not allowed

A workaround is to use the `+=` operator instead.

---

### Src Spec Doc  Type Checking Extensions (`src/spec/doc/_type-checking-extensions.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

[[type-checking-extensions]]
= Type checking extensions

[TIP]
====
This chapter is the SDK reference for *writing* a type checking extension.
For the extensions Groovy already ships with (regex checking, format-string
checking, null safety, frame conditions, purity, parallel-reduction
associativity, and monadic comprehensions), see the
link:typecheckers.html#built-in-auxiliary-type-checkers[Built-in auxiliary type checkers] chapter.
====

== Writing a type checking extension

=== Towards a smarter type checker

Despite being a dynamic language, Groovy can be used with a <<static-type-checking,static type checker>>
at compile time, enabled using the `@TypeChecked` annotation. In this mode, the
compiler becomes more verbose and throws errors for, example, typos, non-existent
methods, etc. This comes with a few limitations though, most of them coming from
the fact that Groovy remains inherently a dynamic language. For example, you
wouldn’t be able to use type checking on code that uses the markup builder:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=intro_stc_extensions,indent=0]
----

In the previous example, none of the `html`, `head`, `body` or `p` methods
exist. However if you execute the code, it works because Groovy uses dynamic dispatch
and converts those method calls at runtime. In this builder, there’s no limitation about
the number of tags that you can use, nor the attributes, which means there is no chance
for a type checker to know about all the possible methods (tags) at compile time, unless
you create a builder dedicated to HTML for example.

Groovy is a platform of choice when it comes to implement internal DSLs. The flexible syntax,
combined with runtime and compile-time metaprogramming capabilities make Groovy an interesting
choice because it allows the programmer to focus on the DSL rather than
on tooling or implementation. Since Groovy DSLs are Groovy code, it’s
easy to have IDE support without having to write a dedicated plugin for
example.

In a lot of cases, DSL engines are written in Groovy (or Java) then user
code is executed as scripts, meaning that you have some kind of wrapper
on top of user logic. The wrapper may consist, for example, in a
`GroovyShell` or `GroovyScriptEngine` that performs some tasks transparently
before running the script (adding imports, applying AST transforms,
extending a base script,…). Often, user written scripts come to
production without testing because the DSL logic comes to a point
where *any* user may write code using the DSL syntax. In the end, a user
may just ignore that what they write is actually *code*. This adds some
challenges for the DSL implementer, such as securing execution of user
code or, in this case, early reporting of errors.

For example, imagine a DSL which goal is to drive a rover on Mars
remotely. Sending a message to the rover takes around 15 minutes. If the
rover executes the script and fails with an error (say a typo), you have
two problems:

* first, feedback comes only after 30 minutes (the time needed for the
rover to get the script and the time needed to receive the error)
* second, some portion of the script has been executed and you may have
to change the fixed script significantly (implying that you need to know
the current state of the rover…)

Type checking extensions is a mechanism that will
allow the developer of a DSL engine to make those scripts safer by
applying the same kind of checks that static type checking allows on
regular groovy classes.

The principle, here, is to fail early, that is
to say fail compilation of scripts as soon as possible, and if possible
provide feedback to the user (including nice error messages).

In short, the idea behind type checking extensions is to make the compiler
aware of all the runtime metaprogramming tricks that the DSL uses, so that
scripts can benefit the same level of compile-time checks as a verbose statically
compiled code would have. We will see that you can go even further by performing
checks that a normal type checker wouldn't do, delivering powerful compile-time
checks for your users.

[[Typecheckingextensions-Howdoesitwork]]
=== The extensions attribute

The `@TypeChecked` annotation supports an attribute
named `extensions`. This parameter takes an array of strings
corresponding to a list of _type checking extensions scripts_. Those
scripts are found at *compile time* on classpath. For example, you would
write:

[source,groovy]
------------------------------------------------------
@TypeChecked(extensions='/path/to/myextension.groovy')
void foo() { ...}
------------------------------------------------------

In that case, the _foo_ methods would be type checked with the rules of
the normal type checker completed by those found in
the _myextension.groovy_ script. Note that while internally the type
checker supports multiple mechanisms to implement type checking
extensions (including plain old java code), the recommended way is to
use those type checking extension scripts.

==== Parameterized extensions

Extensions can accept named parameters using Groovy's named-argument style within the extension string.
The example below uses `NullChecker`, one of the
link:typecheckers.html#built-in-auxiliary-type-checkers[bundled checkers]; the same syntax applies
to any extension that reads the `options` map.

[source,groovy]
------------------------------------------------------
@TypeChecked(extensions = 'groovy.typecheckers.NullChecker(strict: true)')
void foo() { ... }
------------------------------------------------------

Parameters are passed as `key: value` pairs inside parentheses appended to the extension name.
Supported value types include booleans (`true`/`false`), integers, strings (single or double quoted), and `null`.
Multiple parameters are separated by commas.
Note that string values cannot contain commas or colons since these are used as delimiters:

[source,groovy]
------------------------------------------------------
@TypeChecked(extensions = 'com.example.MyChecker(strict: true, threshold: 5, mode: "lenient")')
void foo() { ... }
------------------------------------------------------

Within an extension, the parameters are available via the `options` property, which returns an unmodifiable `Map<String, Object>`:

[source,groovy]
------------------------------------------------------
// in a TypeCheckingDSL extension:
Object run() {
    boolean strict = options?.strict ?: false
    // ...
}
------------------------------------------------------

For precompiled Java extensions (subclasses of `TypeCheckingExtension` or `AbstractTypeCheckingExtension`),
options are accessible via the `getOptions()` method.

The parameterized syntax also works when configuring extensions programmatically:

[source,groovy]
------------------------------------------------------
new ASTTransformationCustomizer(TypeChecked, extensions: ['my.Extension(debug: true)'])
------------------------------------------------------

=== A DSL for type checking
The idea behind type checking extensions is to use a DSL to extend the
type checker capabilities. This DSL allows you to hook into the
compilation process, more specifically the type checking phase, using an
"event-driven" API. For example, when the type checker enters a method
body, it throws a _beforeVisitMethod_ event that the extension can react to:

[source,groovy]
--------------------------------------
beforeVisitMethod { methodNode ->
 println "Entering ${methodNode.name}"
}
--------------------------------------

Imagine that you have this rover DSL at hand. A user would write:

[source,groovy]
--------------
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script,indent=0]
--------------

If you have a class defined as such:

[source,groovy]
----------------------------
include::../test/typing/Robot.groovy[tags=example_robot_classdef,indent=0]
----------------------------

The script can be type checked before being executed using the following
script:

[source,groovy]
------------------------------------------------------------------------------
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup,indent=0]
------------------------------------------------------------------------------
<1> a compiler configuration adds the `@TypeChecked` annotation to all classes
<2> use the configuration in a `GroovyShell`
<3> so that scripts compiled using the shell are compiled with `@TypeChecked` without the user having to add it explicitly

Using the compiler configuration above, we can apply _@TypeChecked_
transparently to the script. In that case, it will fail at compile
time:

------------------------------------------------------------
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_expected_err,indent=0]
------------------------------------------------------------

Now, we will slightly update the configuration to include the
``extensions'' parameter:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_fixed_conf,indent=0]
----

Then add the following to your classpath:

[source,groovy]
.robotextension.groovy
-------------------------------------
include::../test-resources/robotextension.groovy[tags=example_robot_extension,indent=0]
-------------------------------------

Here, we’re telling the compiler that if an _unresolved variable_ is found
and that the name of the variable is _robot_, then we can make sure that the type of this
variable is `Robot`.

[[Typecheckingextensions-TheAPI]]
=== Type checking extensions API

[[Typecheckingextensions-AST]]
==== AST

The type checking API is a low level API, dealing with the Abstract
Syntax Tree. You will have to know your AST well to develop extensions,
even if the DSL makes it much easier than just dealing with AST code
from plain Java or Groovy.

[[Typecheckingextensions-Events]]
==== Events

The type checker sends the following events, to which an extension
script can react:

[[event-setup]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| setup
| *Called When*
| Called after the type checker finished initialization

| *Arguments*
| none
| *Usage*
|
[source,groovy]
----
include::../test-resources/setup.groovy[tags=event,indent=0]
----

Can be used to perform setup of your extension
|===

[[event-finish]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| finish
| *Called When*
| Called after the type checker completed type checking

| *Arguments*
| none
| *Usage*
|
[source,groovy]
----
include::../test-resources/finish.groovy[tags=event,indent=0]
----

Can be used to perform additional checks after the type checker has finished its job.
|===

[[event-unresolvedVariable]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| unresolvedVariable
| *Called When*
| Called when the type checker finds an
  unresolved variable
| *Arguments*
| VariableExpression vexp
| *Usage*
|
[source,groovy]
----
include::../test-resources/unresolvedvariable.groovy[tags=event,indent=0]
----

Allows the developer to help the type checker with user-injected variables.
|===

[[event-unresolvedProperty]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| unresolvedProperty
| *Called When*
| Called when the type checker cannot find
  a property on the receiver
| *Arguments*
| PropertyExpression pexp
| *Usage*
|
[source,groovy]
----
include::../test-resources/unresolvedproperty.groovy[tags=event,indent=0]
----

Allows the developer to handle "dynamic" properties
|===

[[event-unresolvedAttribute]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| unresolvedAttribute
| *Called When*
| Called when the type checker cannot
  find an attribute on the receiver
| *Arguments*
| AttributeExpression aexp
| *Usage*
|
[source,groovy]
----
include::../test-resources/unresolvedattribute.groovy[tags=event,indent=0]
----

Allows the developer to handle missing attributes
|===

[[event-beforeMethodCall]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| beforeMethodCall
| *Called When*
| Called before the type checker starts type
  checking a method call
| *Arguments*
| MethodCall call
| *Usage*
|
[source,groovy]
----
include::../test-resources/beforemethodcall.groovy[tags=event,indent=0]
----

Allows you to intercept method calls before the
type checker performs its own checks. This is useful if you want to
replace the default type checking with a custom one for a limited scope.
In that case, you must set the handled flag to true, so that the type
checker skips its own checks.
|===

[[event-afterMethodCall]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| afterMethodCall
| *Called When*
| Called once the type checker has finished
  type checking a method call
| *Arguments*
| MethodCall call
| *Usage*
|
[source,groovy]
----
include::../test-resources/aftermethodcall.groovy[tags=event,indent=0]
----

Allow you to perform additional checks after the type
checker has done its own checks. This is in particular useful if you
want to perform the standard type checking tests but also want to ensure
additional type safety, for example checking the arguments against each
other.Note that `afterMethodCall` is called even if you did
`beforeMethodCall` and set the handled flag to true.
|===

[[event-onMethodSelection]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| onMethodSelection
| *Called When*
| Called by the type checker when it finds
  a method appropriate for a method call
| *Arguments*
| Expression expr, MethodNode node
| *Usage*
|
[source,groovy]
----
include::../test-resources/onmethodselection.groovy[tags=event,indent=0]
----

The type checker works by inferring
argument types of a method call, then chooses a target method. If it
finds one that corresponds, then it triggers this event. It is for
example interesting if you want to react on a specific method call, such
as entering the scope of a method that takes a closure as argument (as
in builders).Please note that this event may be thrown for various types
of expressions, not only method calls (binary expressions for example).
|===

[[event-methodNotFound]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| methodNotFound
| *Called When*
| Called by the type checker when it fails to
  find an appropriate method for a method call
| *Arguments*
| ClassNode receiver, String name, ArgumentListExpression argList, ClassNode[] argTypes,MethodCall call
| *Usage*
|
[source,groovy]
----
include::../test-resources/methodnotfound.groovy[tags=event,indent=0]
----

Unlike `onMethodSelection`, this event is
sent when the type checker cannot find a target method for a method call
(instance or static). It gives you the chance to intercept the error
before it is sent to the user, but also set the target method.For this,
you need to return a list of `MethodNode`. In most situations, you would
either return: an empty list, meaning that you didn’t find a
corresponding method, a list with exactly one element, saying that there’s
no doubt about the target methodIf you return more than one MethodNode,
then the compiler would throw an error to the user stating that the
method call is ambiguous, listing the possible methods.For convenience,
if you want to return only one method, you are allowed to return it
directly instead of wrapping it into a list.

|===

[[event-beforeVisitMethod]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| beforeVisitMethod
| *Called When*
| Called by the type checker before type
  checking a method body
| *Arguments*
| MethodNode node
| *Usage*
|
[source,groovy]
----
include::../test-resources/beforevisitmethod.groovy[tags=event,indent=0]
----

The type checker will call this method before
starting to type check a method body. If you want, for example, to
perform type checking by yourself instead of letting the type checker do
it, you have to set the handled flag to true. This event can also be used
to help define the scope of your extension (for example, applying it
only if you are inside method foo).
|===

[[event-afterVisitMethod]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| afterVisitMethod
| *Called When*
| Called by the type checker after type
  checking a method body
| *Arguments*
| MethodNode node
| *Usage*
|
[source,groovy]
----
include::../test-resources/aftervisitmethod.groovy[tags=event,indent=0]
----

Gives you the opportunity to perform additional
checks after a method body is visited by the type checker. This is
useful if you collect information, for example, and want to perform
additional checks once everything has been collected.
|===

[[event-beforeVisitClass]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| beforeVisitClass
| *Called When*
| Called by the type checker before type checking a class
| *Arguments*
| ClassNode node
| *Usage*
|
[source,groovy]
----
include::../test-resources/beforevisitclass.groovy[tags=event,indent=0]
----

If a class is type checked, then
before visiting the class, this event will be sent. It is also the case
for inner classes defined inside a class annotated with `@TypeChecked`. It
can help you define the scope of your extension, or you can even totally
replace the visit of the type checker with a custom type checking
implementation. For that, you would have to set the `handled` flag to
`true`. 
|===

[[event-afterVisitClass]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| afterVisitClass
| *Called When*
| Called by the type checker after having finished the visit of a type checked class
| *Arguments*
| ClassNode node
| *Usage*
|
[source,groovy]
----
include::../test-resources/aftervisitclass.groovy[tags=event,indent=0]
----

Called
for every class being type checked after the type checker finished its
work. This includes classes annotated with `@TypeChecked` and any
inner/anonymous class defined in the same class with is not skipped.
|===

[[event-incompatibleAssignment]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| incompatibleAssignment
| *Called When*
| Called when the type checker thinks
    that an assignment is incorrect, meaning that the right-hand side of an
    assignment is incompatible with the left-hand side
| *Arguments*
| ClassNode lhsType, ClassNode rhsType, Expression assignment
| *Usage*
|
[source,groovy]
----
include::../test-resources/incompatibleassignment.groovy[tags=event,indent=0]
----

Gives the
developer the ability to handle incorrect assignments. This is for
example useful if a class overrides `setProperty`, because in that case it
is possible that assigning a variable of one type to a property of
another type is handled through that runtime mechanism. In that case, you
can help the type checker just by telling it that the assignment is
valid (using `handled` set to `true`).
|===

[[event-incompatibleReturnType]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| incompatibleReturnType
| *Called When*
| Called when the type checker thinks that a return value is incompatibe with
    the return type of the enclosing closure or method
| *Arguments*
| ReturnStatement statement, ClassNode valueType
| *Usage*
|
[source,groovy]
----
include::../test-resources/incompatiblereturntype.groovy[tags=event,indent=0]
----

Gives the developer the ability to handle incorrect return values. This is for
example useful when the return value will undergo implicit conversion or the
enclosing closure's target type is difficult to infer properly. In that case,
you can help the type checker just by telling it that the assignment is valid
(by setting the `handled` property).
|===

[[event-ambiguousMethods]]
[cols="1,3a",width="100%"]
|===
| *Event name*
| ambiguousMethods
| *Called When*
| Called when the type checker cannot choose between several candidate methods
| *Arguments*
| List<MethodNode> methods,  Expression origin
| *Usage*
|
[source,groovy]
----
include::../test-resources/ambiguousmethods.groovy[tags=event,indent=0]
----

Gives the
developer the ability to handle incorrect assignments. This is for
example useful if a class overrides `setProperty`, because in that case it
is possible that assigning a variable of one type to a property of
another type is handled through that runtime mechanism. In that case, you
can help the type checker just by telling it that the assignment is
valid (using `handled` set to `true`).
|===

Of course, an extension script may consist of several blocks, and you
can have multiple blocks responding to the same event. This makes the
DSL look nicer and easier to write. However, reacting to events is far
from sufficient. If you know you can react to events, you also need to
deal with the errors, which implies several _helper_ methods that will
make things easier.

[[Typecheckingextensions-Workingwithextensions]]
=== Working with extensions

[[Typecheckingextensions-Supportclasses]]
==== Support classes

The DSL relies on a support class called gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] .
This class itself extends gapi:org.codehaus.groovy.transform.stc.TypeCheckingExtension[] .
Those two classes define a number of _helper_ methods that will make working
with the AST easier, especially regarding type checking. One interesting
thing to know is that you *have access to the type checker*. This means
that you can programmatically call methods of the type checker,
including those that allow you to *throw compilation errors*.

The extension script delegates to the gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] class,
meaning that you have direct access to the following variables:

* _context_: the type checker context, of type gapi:org.codehaus.groovy.transform.stc.TypeCheckingContext[]
* _typeCheckingVisitor_: the type checker itself, a gapi:org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor[] instance
* _generatedMethods_: a list of "generated methods", which is in fact the list of "dummy" methods that you can create
inside a type checking extension using the `newMethod` calls

The type checking context contains a lot of information that is useful
in context for the type checker. For example, the current stack of
enclosing method calls, binary expressions, closures, … This information
is in particular important if you have to know _where_ you are when an
error occurs and that you want to handle it.

In addition to facilities provided by `GroovyTypeCheckingExtensionSupport` and `StaticTypeCheckingVisitor`,
a type-checking DSL script imports static members from gapi:org.codehaus.groovy.ast.ClassHelper[] and
gapi:org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport[] granting access to common types via
`OBJECT_TYPE`, `STRING_TYPE`, `THROWABLE_TYPE`, etc. and checks like `missesGenericsTypes(ClassNode)`,
`isClassClassNodeWrappingConcreteType(ClassNode)` and so on.

[[Typecheckingextensions-Classnodes]]
==== Class nodes

Handling class nodes is something that needs particular attention when
you work with a type checking extension. Compilation works with an
abstract syntax tree (AST) and the tree may not be complete when you are
type checking a class. This also means that when you refer to types, you
must not use class literals such as `String` or `HashSet`, but to class
nodes representing those types. This requires a certain level of
abstraction and understanding how Groovy deals with class nodes. To make
things easier, Groovy supplies several helper methods to deal with class
nodes. For example, if you want to say "the type for String", you can
write:

[source,groovy]
--------------------
include::../test-resources/selfcheck.groovy[tags=classnodefor,indent=0]
--------------------

You would also note that there is a variant of _classNodeFor_ that takes
a `String` as an argument, instead of a `Class`. In general, you
should *not* use that one, because it would create a class node for
which the name is `String`, but without any method, any property, …
defined on it. The first version returns a class node that is _resolved_
but the second one returns one that is _not_. So the latter should be
reserved for very special cases.

The second problem that you might encounter is referencing a type which
is not yet compiled. This may happen more often than you think. For
example, when you compile a set of files together. In that case, if you
want to say "that variable is of type Foo" but `Foo` is not yet
compiled, you can still refer to the `Foo` class node
using `lookupClassNodeFor`:

[source,groovy]
----
include::../test-resources/selfcheck.groovy[tags=lookupclassnodefor,indent=0]
----

[[Typecheckingextensions-Helpingthetypechecker]]
==== Helping the type checker

Say that you know that variable `foo` is of type `Foo` and you want to
tell the type checker about it. Then you can use the `storeType` method,
which takes two arguments: the first one is the node for which you want
to store the type and the second one is the type of the node. If you
look at the implementation of `storeType`, you would see that it
delegates to the type checker equivalent method, which itself does a lot
of work to store node metadata. You would also see that storing the type
is not limited to variables: you can set the type of any expression.

Likewise, getting the type of an AST node is just a matter of
calling `getType` on that node. This would in general be what you want,
but there’s something that you must understand:

* `getType` returns the *inferred type* of an expression. This means
that it will not return, for a variable declared of type `Object` the
class node for `Object`, but the inferred type of this variable *at this
point of the code* (flow typing)
* if you want to access the origin type of a variable (or
field/parameter), then you must call the appropriate method on the AST
node

[[Typecheckingextensions-Throwinganerror]]
==== Throwing an error

To throw a type checking error, you only have to call the
`addStaticTypeError` method which takes two arguments:

* a _message_ which is a string that will be displayed to the end user
* an _AST node_ responsible for the error. It’s better to provide the best
suiting AST node because it will be used to retrieve the line and column
numbers

[[Typecheckingextensions-isXXXExpression]]
==== isXXXExpression

It is often required to know the type of an AST node. For readability,
the DSL provides a special isXXXExpression method that will delegate to
`x instance of XXXExpression`. For example, instead of writing:

[source,groovy]
---------------------------------------
if (node instanceof BinaryExpression) {
   ...
}
---------------------------------------

you can just write:

[source,groovy]
-------------------------------
if (isBinaryExpression(node)) {
   ...
}
-------------------------------

[[Typecheckingextensions-Virtualmethods]]
==== Virtual methods

When you perform type checking of dynamic code, you may often face the
case when you know that a method call is valid but there is no "real"
method behind it. As an example, take the Grails dynamic finders. You
can have a method call consisting of a method named _findByName(…)_. As
there’s no _findByName_ method defined in the bean, the type checker
would complain. Yet, you would know that this method wouldn’t fail at
runtime, and you can even tell what is the return type of this method.
For this case, the DSL supports two special constructs that consist of
_phantom methods_. This means that you will return a method node that
doesn’t really exist but is defined in the context of type checking.
Three methods exist:

* `newMethod(String name, Class returnType)`
* `newMethod(String name, ClassNode returnType)`
* `newMethod(String name, Callable<ClassNode> return Type)`

All three variants do the same: they create a new method node which name
is the supplied name and define the return type of this method.
Moreover, the type checker would add those methods in
the `generatedMethods` list (see `isGenerated` below). The reason why we
only set a name and a return type is that it is only what you need in
90% of the cases. For example, in the `findByName` example upper, the
only thing you need to know is that `findByName` wouldn’t fail at
runtime, and that it returns a domain class. The `Callable` version of
return type is interesting because it defers the computation of the
return type when the type checker actually needs it. This is interesting
because in some circumstances, you may not know the actual return type
when the type checker demands it, so you can use a closure that will be
called each time `getReturnType` is called by the type checker on this
method node. If you combine this with deferred checks, you can achieve
pretty complex type checking including handling of forward references.

[source,groovy]
----------------------------------------------------------------------------------------------
include::../test-resources/newmethod.groovy[tags=newmethod,indent=0]
----------------------------------------------------------------------------------------------

Should you need more than the name and return type, you can always
create a new `MethodNode` by yourself.

[[Typecheckingextensions-Scoping]]
==== Scoping

Scoping is very important in DSL type checking and is one of the reasons
why we couldn’t use a _pointcut_ based approach to DSL type checking.
Basically, you must be able to define very precisely when your extension
applies and when it does not. Moreover, you must be able to handle
situations that a regular type checker would not be able to handle, such
as forward references:

[source,groovy]
---------------------------------------
point a(1,1)
line a,b // b is referenced afterwards!
point b(5,2)
---------------------------------------

Say for example that you want to handle a builder:

[source,groovy]
-------------
builder.foo {
   bar
   baz(bar)
}
-------------

Your extension, then, should only be active once you’ve entered
the `foo` method, and inactive outside this scope. But you could have
complex situations like multiple builders in the same file or embedded
builders (builders in builders). While you should not try to fix all
this from start (you must accept limitations to type checking), the type
checker does offer a nice mechanism to handle this: a scoping stack,
using the `newScope` and `scopeExit` methods.

* `newScope` creates a new scope and puts it on top of the stack
* `scopeExits` pops a scope from the stack

A scope consists of:

* a parent scope
* a map of custom data

If you want to look at the implementation, it’s simply a `LinkedHashMap`
(gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport.TypeCheckingScope[]),
but it’s quite powerful. For example, you can use such a scope to store
a list of closures to be executed when you exit the scope. This is how
you would handle forward references: 

[source,groovy]
------------------------------------------------------
include::../test-resources/scoping.groovy[tags=newscope,indent=0]
include::../test-resources/scoping.groovy[tags=scopeexit,indent=0]
------------------------------------------------------

That is to say, that if at some point you are not able to determine the
type of an expression, or that you are not able to check at this point
that an assignment is valid or not, you can still make the check later…
This is a very powerful feature. Now, `newScope` and `scopeExit`
provide some interesting syntactic sugar:

[source,groovy]
------------------------------------------------------
include::../test-resources/scoping_alt.groovy[tags=newscope,indent=0]
------------------------------------------------------

At anytime in the DSL, you can access the current scope
using `getCurrentScope()` or more simply `currentScope`:

[source,groovy]
------------------------------------------------------
include::../test-resources/scoping_alt.groovy[tags=currentscope,indent=0]
------------------------------------------------------

The general schema would then be:

* determine a _pointcut_ where you push a new scope on stack and
initialize custom variables within this scope
* using the various events, you can use the information stored in your
custom scope to perform checks, defer checks,…
* determine a _pointcut_ where you exit the scope, call `scopeExit`
and eventually perform additional checks

[[Typecheckingextensions-Otherusefulmethods]]
==== Other useful methods

For the complete list of helper methods, please refer to
the gapi:org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport[] and 
gapi:org.codehaus.groovy.transform.stc.TypeCheckingExtension[] classes. However,
take special attention to those methods:

* `isDynamic`: takes a VariableExpression as argument and returns true
if the variable is a DynamicExpression, which means, in a script, that
it wasn’t defined using a type or `def`.
* `isGenerated`: takes a MethodNode as an argument and tells if the
method is one that was generated by the type checker extension using
the `newMethod` method
* `isAnnotatedBy`: takes an AST node and a Class (or ClassNode), and
tells if the node is annotated with this class. For example:
`isAnnotatedBy(node, NotNull)`
* `getTargetMethod`: takes a method call as argument and returns
the `MethodNode` that the type checker has determined for it
* `delegatesTo`: emulates the behaviour of the `@DelegatesTo`
annotation. It allows you to tell that the argument will delegate to a
specific type (you can also specify the delegation strategy)

== Advanced type checking extensions
=== Precompiled type checking extensions

All the examples above use type checking scripts. They are found in source form in classpath, meaning that:

* a Groovy source file, corresponding to the type checking extension, is available on compilation classpath
* this file is compiled by the Groovy compiler for each source unit being compiled (often, a source unit corresponds
to a single file)

It is a very convenient way to develop type checking extensions, however it implies a slower compilation phase, because
of the compilation of the extension itself for each file being compiled. For those reasons, it can be practical to rely
on a precompiled extension. You have two options to do this:

* write the extension in Groovy, compile it, then use a reference to the extension class instead of the source
* write the extension in Java, compile it, then use a reference to the extension class

Writing a type checking extension in Groovy is the easiest path. Basically, the idea is that the type checking extension
script becomes the body of the main method of a type checking extension class, as illustrated here:

[source,groovy]
----
include::../test/typing/PrecompiledExtension.groovy[tags=precompiled_groovy_extension,indent=0]
----
<1> extending the `TypeCheckingDSL` class is the easiest
<2> then the extension code needs to go inside the `run` method
<3> and you can use the very same events as an extension written in source form

Setting up the extension is very similar to using a source form extension:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=setup_precompiled,indent=0]
----

The difference is that instead of using a path in classpath, you just specify the fully qualified class name of the
precompiled extension.

In case you really want to write an extension in Java, then you will not benefit from the type checking extension DSL.
The extension above can be rewritten in Java this way:

[source,java]
----
include::../test/typing/PrecompiledJavaExtension.java[tags=precompiled_java_extension,indent=0]
----
<1> extend the `AbstractTypeCheckingExtension` class
<2> then override the `handleXXX` methods as required

=== Using @Grab in a type checking extension

It is totally possible to use the `@Grab` annotation in a type checking extension.
This means you can include libraries that would only be
available at compile time. In that case, you must understand that you
would increase the time of compilation significantly (at least, the
first time it grabs the dependencies).

=== Sharing or packaging type checking extensions

A type checking extension is just a script that need to be on classpath. As such,
you can share it as is, or bundle it in a jar file that would be added to classpath.

=== Global type checking extensions

While you can configure the compiler to transparently add type checking extensions to your
script, there is currently no way to apply an extension transparently just by having it on
classpath.

=== Type checking extensions and @CompileStatic

Type checking extensions are used with `@TypeChecked` but can also be used with `@CompileStatic`. However, you must
be aware that:

* a type checking extension used with `@CompileStatic` will in general not be sufficient to let the compiler know how
to generate statically compilable code from "unsafe" code
* it is possible to use a type checking extension with `@CompileStatic` just to enhance type checking, that is to say
introduce *more* compilation errors, without actually dealing with dynamic code

Let's explain the first point, which is that even if you use an extension, the compiler will not know how to compile
your code statically: technically, even if you tell the type checker what is the type of a dynamic
variable, for example, it would not know how to compile it. Is it `getBinding('foo')`, `getProperty('foo')`,
`delegate.getFoo()`,…? There's absolutely no direct way to tell the static compiler how to compile such
code even if you use a type checking extension (that would, again, only give hints about the type).

One possible solution for this particular example is to instruct the compiler to use <<mixed-mode,mixed mode compilation>>.
The more advanced one is to use <<ast-xform-as-extension,AST transformations during type checking>> but it is far more
complex.

Type checking extensions allow you to help the type checker where it
fails, but it also allows you to fail where it doesn’t. In that context,
it makes sense to support extensions for `@CompileStatic` too. Imagine
an extension that is capable of type checking SQL queries. In that case,
the extension would be valid in both dynamic and static context, because
without the extension, the code would still pass.

[[mixed-mode]]
=== Mixed mode compilation

In the previous section, we highlighted the fact that you can activate type checking extensions with
`@CompileStatic`. In that context, the type checker would not complain anymore about some unresolved variables or
unknown method calls, but it would still wouldn't know how to compile them statically.

Mixed mode compilation offers a third way, which is to instruct the compiler that whenever an unresolved variable
or method call is found, then it should fall back to a dynamic mode. This is possible thanks to type checking extensions
and a special `makeDynamic` call.

To illustrate this, let's come back to the `Robot` example:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script,indent=0]
----

And let's try to activate our type checking extension using `@CompileStatic` instead of `@TypeChecked`:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_compilestatic,indent=0]
----
<1> Apply `@CompileStatic` transparently
<2> Activate the type checking extension

The script will run fine because the static compiler is told about the type of the `robot` variable, so it is capable
of making a direct call to `move`. But before that, how did the compiler know how to get the `robot` variable? In fact
by default, in a type checking extension, setting `handled=true` on an unresolved variable will automatically trigger
a dynamic resolution, so in this case you don't have anything special to make the compiler use a mixed mode. However,
let's slightly update our example, starting from the robot script:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script_direct,indent=0]
----

Here you can notice that there is no reference to `robot` anymore. Our extension will not help then because we will not
be able to instruct the compiler that `move` is done on a `Robot` instance. This example of code can be executed in a
totally dynamic way thanks to the help of a gapi:groovy.util.DelegatingScript[]:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_dynamic,indent=0]
----
<1> we configure the compiler to use a `DelegatingScript` as the base class
<2> the script source needs to be parsed and will return an instance of `DelegatingScript`
<3> we can then call `setDelegate` to use a `Robot` as the delegate of the script
<4> then execute the script. `move` will be directly executed on the delegate

If we want this to pass with `@CompileStatic`, we have to use a type checking extension, so let's update our configuration:

[source,groovy]
----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_compilestatic2,indent=0]
----
<1> apply `@CompileStatic` transparently
<2> use an alternate type checking extension meant to recognize the call to `move`

Then in the previous section we have learnt how to deal with unrecognized method calls, so we are able to write this
extension:

[source,groovy]
.robotextension2.groovy
-------------------------------------
include::../test-resources/robotextension2.groovy[tags=example_robot_extension,indent=0]
-------------------------------------
<1> if the call is a method call (not a static method call)
<2> that this call is made on "implicit this" (no explicit `this.`)
<3> that the method being called is `move`
<4> and that the call is done with a single argument
<5> and that argument is of type `int`
<6> then tell the type checker that the call is valid
<7> and that the return type of the call is `Robot`

If you try to execute this code, then you could be surprised that it actually fails at runtime:

----
include::../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=robot_runtime_error_cs,indent=0]
----

The reason is very simple: while the type checking extension is sufficient for `@TypeChecked`, which does not involve
static compilation, it is not enough for `@CompileStatic` which requires additional information. In this case, you told
the compiler that the method existed, but you didn't explain to it *what* method it is in reality, and what is the
receiver of the message (the delegate).

Fixing this is very easy and just implies replacing the `newMethod` call with something else:

[source,groovy]
.robotextension3.groovy
-------------------------------------
include::../test-resources/robotextension3.groovy[tags=example_robot_extension,indent=0]
-------------------------------------
<1> tell the compiler that the call should be made dynamic

The `makeDynamic` call does 3 things:

* it returns a virtual method just like `newMethod`
* automatically sets the `handled` flag to `true` for you
* but also marks the `call` to be done dynamically

So when it comes time for the compiler to generate bytecode for the call to `move`, since it is now marked as a dynamic call,
it falls back to the dynamic compiler and lets it handle the call. And since the extension tells us that the return
type of the dynamic call is a `Robot`, subsequent calls will be done statically!

Some might wonder why the static compiler doesn't do this by default without an extension. It is a design decision.
If the code is statically compiled, we normally want compile-time type safety and the best performance.
If unrecognized variables/method calls were automatically made dynamic, you'd partially lose compile-time type safety.
Typos and some scenarios of incorrect typing would no longer be caught at compile time!

In short, if you want to have mixed mode compilation, it *has* to be explicit, through a type checking extension, so
that the compiler, and the designer of the DSL, are totally aware of exactly when typing rules are relaxed.

`makeDynamic` can be used on 3 kinds of AST nodes:

* a method node (`MethodNode`)
* a variable (`VariableExpression`)
* a property expression (`PropertyExpression`)

If that is not enough, then it means that static compilation cannot be done directly and that you have to rely on AST
transformations.

[[ast-xform-as-extension]]
=== Transforming the AST in an extension

Type checking extensions look very attractive from an AST transformation design point of view: extensions have access
to context like inferred types, which is often nice to have. And an extension has a direct access to the abstract
syntax tree. Since you have access to the AST, there is nothing in theory that prevents
you from modifying the AST. However, we do not recommend you to do so, unless you are an advanced AST transformation
designer and well aware of the compiler internals:

* First of all, you would explicitly break the contract of type checking, which is to annotate,
and only annotate the AST. Type checking should *not* modify the AST tree because you wouldn’t be able to
guarantee anymore that code without the _@TypeChecked_ annotation
behaves the same without the annotation.
* If your extension is meant to work with _@CompileStatic_, then you *can* modify the AST because
this is indeed what _@CompileStatic_ will eventually do. Static compilation doesn’t guarantee the same semantics at
dynamic Groovy so there is effectively a difference between code compiled with _@CompileStatic_ and code compiled
with _@TypeChecked_. It’s up to you to choose whatever strategy you want to update the AST, but probably
using an AST transformation that runs before type checking is easier.
* if you cannot rely on a transformation that kicks in before the type checker, then you must be *very* careful

WARNING: The type checking phase is the last phase running in the compiler before bytecode generation. All other AST
transformations run before that and the compiler does a very good job at "fixing" incorrect AST generated before the
type checking phase. As soon as you perform a transformation during type checking, for example directly in a type
checking extension, then you have to do all this work of generating a 100% compiler compliant abstract syntax tree by
yourself, which can easily become complex. That's why we do not recommend to go that way if you are beginning with
type checking extensions and AST transformations.

=== Examples

Examples of real life type checking extensions are easy to find. You can download the source code for Groovy and
take a look at the
https://github.com/apache/groovy/blob/master/src/test/groovy/groovy/transform/stc/TypeCheckingExtensionsTest.groovy[TypeCheckingExtensionsTest]
class which is linked to
https://github.com/apache/groovy/tree/master/src/test-resources/groovy/transform/stc[various extension scripts].

An example of a complex type checking extension can be found in the link:templating.html#_the_markuptemplateengine[Markup Template Engine]
source code: this template engine relies on a type checking extension and AST transformations to transform templates into
fully statically compiled code. Sources for this can be found
https://github.com/apache/groovy/tree/master/subprojects/groovy-templates/src/main/groovy/groovy/text/markup[here].

---

### Src Spec Doc  Working With Arrays (`src/spec/doc/_working-with-arrays.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Working with arrays
:gdk: http://www.groovy-lang.org/gdk.html[Groovy development kit]

Groovy provides array support based on Java arrays with several extensions found in the {gdk}. The overall
intention is that whether you are using an array or a collection, the code for working with the aggregate remains the same.

[[Arrays]]
== Arrays

=== Array literals

You can create arrays as follows. Notice that `[]` is also used as the empty array
expression when given an explicit array type.

[source,groovy]
-------------------------------------
include::../test/gdk/WorkingWithArraysTest.groovy[tags=array_literals,indent=0]
-------------------------------------

=== Iterating on an array

Iterating on elements of an array is usually done calling the `each` and `eachWithIndex` methods, which execute code on each
item of an array:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithArraysTest.groovy[tags=array_each,indent=0]
----------------------------------------------------------------------------

=== Other useful methods

There are numerous other GDK methods for working with arrays.
Just be a little careful to read the documentation.
For collections, there are some mutating methods which alter
the original collection and others which produce new collections,
leaving the original untouched.
Since arrays are of a fixed size, we wouldn't expect mutating
methods which altered an array's size. Often instead, such methods return
collections. Here are some interesting array GDK methods:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithArraysTest.groovy[tags=array_gdk,indent=0]
----------------------------------------------------------------------------

---

### Src Spec Doc  Working With Collections (`src/spec/doc/_working-with-collections.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Working with collections
:gdk: http://www.groovy-lang.org/gdk.html[Groovy development kit]
:java-util-list: http://docs.oracle.com/javase/8/docs/api/java/util/List.html[java.util.List]
:java-lang-comparable: java.lang.Comparable

Groovy provides native support for various collection types, including <<Collections-Lists,lists>>,
<<Collections-Maps,maps>> or <<Collections-Ranges,ranges>>. Most of those are based on the Java
collection types and decorated with additional methods found in the {gdk}.

[[Collections-Lists]]
== Lists

=== List literals

You can create lists as follows. Notice that `[]` is the empty list
expression.

[source,groovy]
-------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_literals,indent=0]
-------------------------------------

Each list expression creates an implementation of {java-util-list}.

Of course lists can be used as a source to construct another list:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_construct,indent=0]
----------------------------------------------------------------------------


A list is an ordered collection of objects:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_usecases,indent=0]
----------------------------------------------------------------------------

=== List as a boolean expression

Lists can be evaluated as a `boolean` value:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_to_bool,indent=0]
----------------------------------------------------------------------------

=== Iterating on a list

Iterating on elements of a list is usually done calling the `each` and `eachWithIndex` methods, which execute code on each
item of a list:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_each,indent=0]
----------------------------------------------------------------------------

In addition to iterating, it is often useful to create a new list by transforming each of its elements into
something else. This operation, often called mapping, is done in Groovy thanks to the `collect` method:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_collect,indent=0]
----------------------------------------------------------------------------

When each element maps to a collection of results, `collectMany` transforms and flattens in a single step.
It is the idiomatic (and more efficient) alternative to `collect { ... }.flatten()`:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_collectMany,indent=0]
----------------------------------------------------------------------------

To build a `Map` from a list, `collectEntries` collects a key/value pair for each element:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_collectEntries,indent=0]
----------------------------------------------------------------------------

When you need each element together with its position, `withIndex` provides a more composable alternative
to `eachWithIndex`, while `indexed` returns a map from index to element:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_withIndex,indent=0]
----------------------------------------------------------------------------

=== Manipulating lists

[[List-Filtering]]
==== Filtering and searching

The {gdk} contains a lot of methods on collections that enhance
the standard collections with pragmatic methods, some of which are illustrated here:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk1,indent=0]
----------------------------------------------------------------------------

And here is idiomatic Groovy code for finding the maximum and minimum in a collection:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk2,indent=0]
----------------------------------------------------------------------------

In addition to closures, you can use a `Comparator` to define the comparison criteria:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_comparator,indent=0]
----------------------------------------------------------------------------

==== Adding or removing elements

We can use `[]` to assign a new empty list and `<<` to append items to it:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_leftshift,indent=0]
----------------------------------------------------------------------------

We can add to a list in many ways:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_add,indent=0]
----------------------------------------------------------------------------

It is however important that the `+` operator on a list is *not mutating*. Compared to `<<`, it will create a new
list, which is often not what you want and can lead to performance issues.

The {gdk} also contains methods allowing you to easily remove elements from a list by value:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk3,indent=0]
----------------------------------------------------------------------------

It is also possible to remove an element by passing its index to the `remove` method, in which case the list is mutated:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk_remove_index,indent=0]
----------------------------------------------------------------------------

In case you only want to remove the first element having the same value in a list, instead of removing all
elements, you can call the `remove` method passing the value:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk5,indent=0]
----------------------------------------------------------------------------

As you can see, there are two `remove` methods available.  One that takes an integer and removes an element
by its index, and another that will remove the first element that matches the passed value.  So what should we 
do when we have a list of integers?  In this case, you may wish to use `removeAt` to remove an element by its
index, and `removeElement` to remove the first element that matches a value.

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk4,indent=0]
----------------------------------------------------------------------------

Of course, `removeAt` and `removeElement` will work with lists of any type.

Additionally, removing all the elements in a list can be done by calling the `clear` method:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk6,indent=0]
----------------------------------------------------------------------------

==== Set operations

The {gdk} also includes methods making it easy to reason on sets:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk7,indent=0]
----------------------------------------------------------------------------

==== Sorting

Working with collections often implies sorting. Groovy offers a variety of options to sort lists,
from using closures to comparators, as in the following examples:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_sort,indent=0]
----------------------------------------------------------------------------

==== Removing duplicates

The `unique` method removes duplicate elements *in place*, while `toUnique` returns a *new* list, leaving the
original untouched. Both accept an optional closure or comparator to define what "the same" means:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_unique,indent=0]
----------------------------------------------------------------------------

==== Taking and dropping elements

Groovy can select or discard elements from either end of a list, either by count (`take`, `drop`, `takeRight`,
`dropRight`) or by predicate (`takeWhile`, `dropWhile`). None of these methods mutate the original list:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_take_drop,indent=0]
----------------------------------------------------------------------------

==== Duplicating elements

The {gdk} also takes advantage of operator overloading to provide methods allowing duplication of elements
of a list:

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_multiply,indent=0]
----------------------------------------------------------------------------

[[Collections-Maps]]
== Maps

=== Map literals

In Groovy, maps (also known as associative arrays) can be created using the map literal syntax: `[:]`:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_literal,indent=0]
--------------------------------------------------

Map keys are strings by default: `[a:1]` is equivalent to `['a':1]`. This can be confusing if you define a variable
named `a` and that you want the *value* of `a` to be the key in your map. If this is the case, then you *must* escape
the key by adding parenthesis, like in the following example:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_literal_gotcha,indent=0]
--------------------------------------------------

In addition to map literals, it is possible, to get a new copy of a map, to clone it:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_construct,indent=0]
--------------------------------------------------

The resulting map is a *shallow* copy of the original one, as illustrated in the previous example.

=== Map property notation

Maps also act like beans so you can use the property notation to get/set
items inside the `Map` as long as the keys are strings which are valid
Groovy identifiers:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_property,indent=0]
--------------------------------------------------

Note: by design `map.foo` will always look for the key `foo` in the map. This
means `foo.class` will return `null` on a map that doesn't contain the `class` key. Should you really want to know
the class, then you must use `getClass()`:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_property_gotcha,indent=0]
--------------------------------------------------

[[Maps-PropertyVsSubscript]]
==== Property access versus subscript and `get`

Because `map.k` reads the *key* `k` (rather than a bean property), property access, the subscript operator
and `get` can diverge once a key collides with a real property. Every cell in the tables below is included
from a passing assertion in `WorkingWithCollectionsTest`, so they always reflect the current runtime.

For a *plain* map there are only entries, so all four forms agree:

[cols="2,^1a,^1a,^1a,^1a",options="header"]
.Plain map (`[foo:'bar']`, `[class:'C']`, `[:]`)
|===
| key | `m.k` | `m.k` (`@CompileStatic`) | `m['k']` | `m.get('k')`

| ordinary (`'foo'`)
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_ordinary,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_ordinary,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_ordinary,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_ordinary,indent=0]

| meta-name present (`'class'`)
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_present,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_present,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_present,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_present,indent=0]

| meta-name absent (`'class'`)
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_absent,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_absent,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_absent,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t1_absent,indent=0]
|===

A map *subclass* can declare real properties. Then `m.k` reads the property (identically under dynamic and
`@CompileStatic` compilation), while `m['k']` and `m.get('k')` read the entry:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_class,indent=0]
--------------------------------------------------

then, after `m.put('foo', 11)` and `m.put('baz', 33)`:

[cols="2,^1a,^1a,^1a,^1a",options="header"]
.Map subclass with declared properties `foo`, `bar`
|===
| key | `m.k` | `m.k` (`@CompileStatic`) | `m['k']` | `m.get('k')`

| `'foo'` (property=1, entry=11)
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_foo_prop,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_foo_prop,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_foo_entry,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_foo_entry,indent=0]

| `'bar'` (property=2, no entry)
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_bar_prop,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_bar_prop,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_bar_entry,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_bar_entry,indent=0]

| `'baz'` (no property, entry=33)
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_baz,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_baz,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_baz,indent=0]
a|
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=t2_baz,indent=0]
|===

Two things to take away: after the addition of `getAt(Map, String)`/`putAt(Map, String, V)`, `m['k']` is
equivalent to `m.get('k')` in every row and both compilation modes; and `m.k` resolves to a declared
property when one exists (use `['k']`/`get` to be sure of reading the entry).

The tables above all use an explicit receiver `m`. A separate gotcha applies to an *unqualified* name read
inside the body of a `Map` subclass -- a method, a `with(map) { ... }` block, or an anonymous-inner-class
initializer. There the implicit receiver is the map itself, so the name is a property read on `this` and
resolves to the *entry*, not to any binding in an enclosing scope. From Groovy 5, this self property takes
precedence over an enclosing-class field of the same name (see https://issues.apache.org/jira/browse/GROOVY-10985[GROOVY-10985]),
so such a reference silently yields `null` for a missing entry rather than reading the field:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tag=bare_self_shadow,indent=0]
--------------------------------------------------

Qualify the outer reference (`Outer.NAME` above) to read the enclosing field.

=== Iterating on maps

As usual in the {gdk}, idiomatic iteration on maps makes use of the `each` and `eachWithIndex` methods.
It's worth noting that maps created using the map literal notation are *ordered*, that is to say that if you iterate
on map entries, it is guaranteed that the entries will be returned in the same order they were added in the map.

[source,groovy]
--------------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_iteration,indent=0]
--------------------------------------------------------------------------------

=== Manipulating maps

==== Adding or removing elements

Adding an element to a map can be done either using the `put` method, the subscript operator or using `putAll`:

[source,groovy]
---------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_add,indent=0]
---------------------

Removing all the elements of a map can be done by calling the `clear` method:

[source,groovy]
---------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_gdk1,indent=0]
---------------------

Maps generated using the map literal syntax are using the object `equals` and `hashcode` methods. This means that
you should *never* use an object which hash code is subject to change over time, or you wouldn't be able to get
the associated value back.

It is also worth noting that you should *never* use a `GString` as the key of a map, because the hash code of a `GString`
is not the same as the hash code of an equivalent `String`:

[source,groovy]
---------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=gstring_gotcha,indent=0]
---------------------

[[JN1035-Maps-Collectionviewsofamap]]
==== Keys, values and entries

We can inspect the keys, values, and entries in a view:

[source,groovy]
-------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_views,indent=0]
-------------------------------------------------------------------------

Mutating values returned by the view (be it a map entry, a key or a value) is highly discouraged because success
of the operation directly depends on the type of the map being manipulated. In particular, Groovy relies on collections
from the JDK that in general make no guarantee that a collection can safely be manipulated through `keySet`, `entrySet`, or
`values`.

==== Filtering and searching

The {gdk} contains filtering, searching and collecting methods similar to those found
for <<List-Filtering,lists>>:

[source,groovy]
-----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_gdk2,indent=0]
-----------------------------------------------------------------------------

[[Maps-Grouping]]
==== Grouping

We can group a list into a map using some criteria:

[source,groovy]
----------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_gdk3,indent=0]
----------------------------------------------------------------

[[Maps-WithDefault]]
==== Maps with a default value

The `withDefault` method wraps a map so that reading a missing key returns (and stores) a value computed by
a closure. This is particularly handy for accumulating into per-key collections without having to pre-populate
them:

[source,groovy]
----------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=map_withDefault,indent=0]
----------------------------------------------------------------

NOTE: Since Groovy 6, under static compilation, calling `withDefault` on a map with statically-known key/value
types automatically selects the type-checked variant: the wrapped map rejects ill-typed keys and values at
runtime instead of silently growing entries that violate the map's declared generics
(link:https://issues.apache.org/jira/browse/GROOVY-11807[GROOVY-11807]). Code that (usually inadvertently)
relied on the lenient behaviour can defer the upgrade with the
`groovy.classtag.preemption.disable` system property — see the
link:core-semantics.html#classtag-annotation[`@ClassTag` documentation] for details. Dynamic code is
unaffected.

[[Collections-Ranges]]
== Ranges

Ranges allow you to create a list of sequential values. These can be
used as `List` since
http://docs.groovy-lang.org/latest/html/api/groovy/lang/Range.html[Range] extends
{java-util-list}.

Ranges defined with the `..` notation are inclusive (that is the list
contains the from and to value).

Ranges defined with the `..<` notation are half-open, they include the
first value but not the last value.

Ranges defined with the `<..` notation are also half-open, they include the
last value but not the first value.

Ranges defined with the `<..<` notation are full-open, they do not include the
first value nor the last value.

[source,groovy]
----------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=intrange,indent=0]
----------------------------------------------------------------------------

Note that int ranges are implemented efficiently, creating a lightweight
Java object containing a from and to value.

Ranges can be used for any Java object which implements {java-lang-comparable}
for comparison and also have methods `next()` and `previous()` to return the
next / previous item in the range. For example, you can create a range of `String` elements:

[source,groovy]
--------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=stringrange,indent=0]
--------------------------------------

You can iterate on a range using a `for` loop:

[source,groovy]
----------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=range_for,indent=0]
----------------------

but alternatively you can achieve the same effect in a more Groovy idiomatic style, by iterating a range
with `each` method:

[source,groovy]
----------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=range_each,indent=0]
----------------------

Ranges can be also used in the `switch` statement:

[source,groovy]
----------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=range_switch,indent=0]
----------------------

== Syntax enhancements for collections

=== GPath support

Thanks to the support of property notation for both lists and maps, Groovy provides syntactic sugar making it
really easy to deal with nested collections, as illustrated in the following examples:

[source,groovy]
------------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=gpath_support_1,indent=0]
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=gpath_support_2,indent=0]
------------------------------------------------------------------------------

=== Spread operator

The spread operator can be used to "inline" a collection into another. It is syntactic sugar which often avoids calls
to `putAll` and facilitates the realization of one-liners:

[source,groovy]
------------------------------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=gpath_support_3,indent=0]
------------------------------------------------------------------------------

[[Collections-Gettingefficientwiththestar-dotoperator]]
=== The star-dot `*.' operator

The "star-dot" operator is a shortcut operator allowing you to call a method or a property on all elements of a
collection:

[source,groovy]
-------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=stardot_1,indent=0]

include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=stardot_2,indent=0]
-------------------------------------------------

[[Collections-Slicingwiththesubscriptoperator]]
=== Slicing with the subscript operator

You can index into lists, arrays, maps using the subscript expression. It is interesting that strings
are considered as special kinds of collections in that context:

[source,groovy]
--------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=subscript,indent=0]
--------------------------------------------------

Notice that you can use ranges to extract part of a collection:

[source,groovy]
-----------------------------------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=subscript_2,indent=0]
-----------------------------------------------------------

The subscript operator can be used to update an existing collection (for collection type which are not immutable):

[source,groovy]
---------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=subscript_3,indent=0]
---------------------------------

It is worth noting that negative indices are allowed, to extract more easily from the end of a collection:

[source,groovy]
---------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=subscript_4,indent=0]
---------------------------------

You can use negative indices to count from the end of the List, array,
String etc.

[source,groovy]
--------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=subscript_4a,indent=0]
--------------------------------

Eventually, if you use a backwards range (the starting index is greater than
the end index), then the answer is reversed.

[source,groovy]
--------------------------------
include::../test/gdk/WorkingWithCollectionsTest.groovy[tags=subscript_5,indent=0]
--------------------------------

[[Collections-EnhancedCollectionMethods]]
== Enhanced Collection Methods

In addition to <<Collections-Lists,lists>>, <<Collections-Maps,maps>> or <<Collections-Ranges,ranges>>, Groovy offers
a lot of additional methods for filtering, collecting, grouping, counting, ... which are directly available on either
collections or more easily iterables.

In particular, we invite you to read the {gdk} API docs and specifically:

* methods added to `Iterable` can be found http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Iterable.html[here]
* methods added to `Iterator` can be found http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Iterator.html[here]
* methods added to `Collection` can be found http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Collection.html[here]
* methods added to `List` can be found http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/List.html[here]
* methods added to `Map` can be found http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html[here]

---

### Src Spec Doc  Working With Io (`src/spec/doc/_working-with-io.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Working with IO

Groovy provides a number of
link:gdk.html[helper methods] for working
with I/O. While you could use standard Java code in Groovy to deal with those,
Groovy provides much more convenient ways to handle files, streams, readers, ...

In particular, you should take a look at methods added to:

* the `java.io.File` class : http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html
* the `java.io.InputStream` class: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html
* the `java.io.OutputStream` class: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/OutputStream.html
* the `java.io.Reader` class: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Reader.html
* the `java.io.Writer` class: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Writer.html
* the `java.nio.file.Path` class: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/nio/file/Path.html

The following section focuses on sample idiomatic constructs using helper methods available above but is not meant
to be a complete description of all available methods. For that, please read the link:gdk.html[GDK API].

== Reading files

As a first example, let's see how you would print all lines of a text file in Groovy:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=print_file_lines,indent=0]
----

The `eachLine` method is a method added to the `File` class automatically by Groovy and has many variants, for example
if you need to know the line number, you can use this variant:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=print_file_lines2,indent=0]
----

If for whatever reason an exception is thrown in the `eachLine` body, the method makes sure that the resource
is properly closed. This is true for all I/O resource methods that Groovy adds.

For example in some cases you will prefer to use a `Reader`, but still benefit from the automatic resource management
from Groovy. In the next example, the reader *will* be closed even if the exception occurs:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=withreader_exception,indent=0]
----

Should you need to collect the lines of a text file into a list, you can do:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=collect_lines,indent=0]
----

Or you can even leverage the `as` operator to get the contents of the file into an array of lines:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=lines_as_strings,indent=0]
----

How many times did you have to get the contents of a file into a `byte[]` and how much code does it require? Groovy
makes it very easy actually:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=file_bytes,indent=0]
----

Groovy also provides asynchronous variants for reading and writing files via the `groovy-nio` module.
These return a `CompletableFuture`, making them composable and easy to use with async frameworks.

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=async_read,indent=0]
----

Similarly, `path.bytesAsync` returns a `CompletableFuture<byte[]>`, and
`path.writeAsync(text)` writes content asynchronously.

Working with I/O is not limited to dealing with files. In fact, a lot of operations rely on input/output streams,
hence why Groovy adds a lot of support methods to those, as you can see in the
http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html[documentation].

As an example, you can obtain an `InputStream` from a `File` very easily:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=newinputstream,indent=0]
----

However you can see that it requires you to deal with closing the inputstream. In Groovy it is in general a better
idea to use the `withInputStream` idiom that will take care of that for you:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=withinputstream,indent=0]
----

== Writing files

Of course in some cases you won't want to read but write a file. One of the options is to use a `Writer`:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=withwriter_example,indent=0]
----

But for such a simple example, using the `<<` operator would have been enough:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=file_leftshift,indent=0]
----

Of course we do not always deal with text contents, so you could use the `Writer` or directly write bytes as in
this example:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=file_setbytes,indent=0]
----

Of course you can also directly deal with output streams. For example, here is how you would create an output
stream to write into a file:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=newoutputstream,indent=0]
----

However you can see that it requires you to deal with closing the output stream. Again it is in general a better
idea to use the `withOutputStream` idiom that will handle the exceptions and close the stream in any case:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=withoutputstream,indent=0]
----

== Traversing file trees

In scripting contexts it is a common task to traverse a file tree in order to find some specific files and do
something with them. Groovy provides multiple methods to do this. For example you can perform something on all files
of a directory:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=eachfile,indent=0]
----
<1> executes the closure code on each file found in the directory
<2> executes the closure code on files in the directory matching the specified pattern

Often you will have to deal with a deeper hierarchy of files, in which case you can use `eachFileRecurse`:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=eachfilerecurse,indent=0]
----
<1> executes the closure code on each file or directory found in the directory, recursively
<2> executes the closure code only on files, but recursively

For more complex traversal techniques you can use the `traverse` method, which requires you to set a special flag
indicating what to do with the traversal:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=traverse,indent=0]
----
<1> if the current file is a directory and its name is `bin`, stop the traversal
<2> otherwise print the file name and continue

== Data and objects

In Java it is not uncommon to serialize and deserialize data using the `java.io.DataOutputStream` and
`java.io.DataInputStream` classes respectively. Groovy will make it even easier to deal with them. For example, you could
serialize data into a file and deserialize it using this code:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=data_in_out,indent=0]
----

And similarly, if the data you want to serialize implements the `Serializable` interface, you can proceed with
an object output stream, as illustrated here:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=object_in_out,indent=0]
----

[[process-management]]
== Executing External Processes

The previous section described how easy it was to deal with files, readers or streams in Groovy. However in domains
like system administration or devops it is often required to communicate with external processes.

Groovy provides `execute` and `toProcessBuilder` methods as two mechanisms to execute external processes.
In simple cases, calls to `execute()`
are invoked directly on a command string:

[source,groovy]
----
"javac src/main/java/*.java".execute()
----

For more sophisticated workloads, a _named-parameter_ variant configures
the process with options like working directory,
environment, and stream redirection:

[source,groovy]
----
def result = "javac src/main/java/*.java".execute(
    dir: new File('/myproject'),
    redirectErrorStream: true
).waitForResult(2, TimeUnit.MINUTES)

if (!result.ok) System.err.println result.out
----

The `toProcessBuilder()` method lets you piggyback directly onto
the `ProcessBuilder` fluent API:

[source,groovy]
----
def result = "javac src/main/java/*.java".toProcessBuilder()
    .directory(new File('/myproject'))
    .redirectErrorStream(true)
    .start()
    .waitForResult(2, TimeUnit.MINUTES)

if (!result.ok) System.err.println result.out
----

The `execute()` and `start()` methods return a `java.lang.Process` instance, and
`waitForResult()` returns a `ProcessResult` capturing stdout, stderr, and the exit code.
The following sections cover each approach in detail.

=== Simple execution

Simply write the command line as a string and call the `execute()` method.
E.g., on a *nix machine (or a Windows machine with appropriate *nix
commands installed), you can execute this:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=process_list_files,indent=0]
----
<1> executes the `ls` command in an external process
<2> consume the output of the command and retrieve the text

Here is the same command as above but we will now process the
resulting stream a line at a time:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=process_list_files_line_by_line,indent=0]
----
<1> executes the `ls` command in an external process
<2> for each line of the input stream of the process
<3> print the line

It is worth noting that `in` corresponds to an input stream to the standard output of the command. `out` will refer
to a stream where you can send data to the process (its standard input).

Remember that many commands are shell built-ins and need special
handling. So if you want a listing of files in a directory on a Windows
machine and write:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=dir_windows,indent=0]
----

you will receive an `IOException` saying  _Cannot run program "dir":
CreateProcess error=2, The system cannot find the file specified._

This is because `dir` is built-in to the Windows shell (`cmd.exe`) and
can't be run as a simple executable. Instead, you will need to write:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=dir_windows_fixed,indent=0]
----

=== Named parameters for execute

The `execute()` method accepts named parameters to configure the process.
Supported options include `dir` (working directory), `env` (environment
variables), `redirectErrorStream`, `inheritIO`, `outputFile`, `errorFile`,
`inputFile`, `appendOutput`, and `appendError`.
The file-related options (`dir`, `outputFile`, `errorFile`, `inputFile`,
`appendOutput`, `appendError`) accept a `File`, `Path`, or `String`:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=execute_named_params,indent=0]
----

To merge stderr into stdout:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=execute_redirect_error,indent=0]
----

=== Using ProcessBuilder directly

For full control over process construction, the `toProcessBuilder()` method
creates a `java.lang.ProcessBuilder` from a command string, array, or list:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=to_process_builder,indent=0]
----

=== Capturing output, error, and exit code

A common need is to capture a process's standard output, standard error,
and exit code all at once. The `waitForResult()` method returns a
`ProcessResult` with `out`, `err`, `exitCode`, and `ok` properties:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=waitforresult,indent=0]
----

If the process produces an error:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=waitforresult_error,indent=0]
----

A timeout variant is available that forcibly kills the process if it
exceeds the given duration:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=waitforresult_timeout,indent=0]
----

=== Stream handling

Because some native platforms only provide limited buffer size for
standard input and output streams, failure to promptly write the input
stream or read the output stream of the subprocess may cause the
subprocess to block, and even deadlock.

Because of this, Groovy provides some additional helper methods which
make stream handling for processes easier.

Here is how to gobble all of the output (including the error stream
output) from your process:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=consumeoutput,indent=0]
----

There are also variations of `consumeProcessOutput` that make use of `StringBuffer`, `InputStream`,
`OutputStream` etc... For a complete list, please read the
http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Process.html[GDK API for java.lang.Process]

=== Piping

The `pipeTo` command (mapped to `|` to allow overloading) lets the output
stream of one process be fed into the input stream of another process.

Here are some examples of use:

[source,groovy]
.Pipes in action
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=pipe_example_1,indent=0]
----

[source,groovy]
.Consuming errors
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=pipe_example_2,indent=0]
----

For more robust piping, the `pipeline()` method uses native OS-level piping
via `ProcessBuilder.startPipeline()`:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=pipeline,indent=0]
----

=== Asynchronous notifications

The `onExit` method registers a closure to be called when the process
terminates:

[source,groovy]
----
include::../test/gdk/WorkingWithIOSpecTest.groovy[tags=on_exit,indent=0]
----

---

### Src Spec Doc  Working With Numbers (`src/spec/doc/_working-with-numbers.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Numbers
:gdk: http://www.groovy-lang.org/gdk.html[Groovy development kit]

Groovy supports different kinds of integral literals and decimal literals, backed by the usual `Number` types of Java.

== Integral literals

The integral literal types are the same as in Java:

* `byte`
* `char`
* `short`
* `int`
* `long`
* `java.math.BigInteger`

You can create integral numbers of those types with the following declarations:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=int_decl,indent=0]
----

If you use optional typing by using the `def` keyword, the type of the integral number will vary:
it'll adapt to the capacity of the type that can hold that number.

For positive numbers:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=wide_int_positive,indent=0]
----

As well as for negative numbers:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=wide_int_negative,indent=0]
----

=== Alternative non-base 10 representations

Numbers can also be represented in binary, octal, hexadecimal and decimal bases.

==== Binary literal

Binary numbers start with a `0b` prefix:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=binary_literal_example,indent=0]
----

==== Octal literal

Octal numbers are specified in the typical format of `0` followed by octal digits.

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=octal_literal_example,indent=0]
----

==== Hexadecimal literal

Hexadecimal numbers are specified in the typical format of `0x` followed by hex digits.

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=hexadecimal_literal_example,indent=0]
----

== Decimal literals

The decimal literal types are the same as in Java:

* `float`
* `double`
* `java.math.BigDecimal`

You can create decimal numbers of those types with the following declarations:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=float_decl,indent=0]
----

Decimals can use exponents, with the `e` or `E` exponent letter, followed by an optional sign,
and an integral number representing the exponent:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=float_exp,indent=0]
----

Conveniently for exact decimal number calculations, Groovy chooses `java.math.BigDecimal` as its decimal number type.
In addition, both `float` and `double` are supported, but require an explicit type declaration, type coercion or suffix.
Even if `BigDecimal` is the default for decimal numbers, such literals are accepted in methods or closures taking `float` or `double` as parameter types.

NOTE: Decimal numbers can't be represented using a binary, octal or hexadecimal representation.

== Underscore in literals

When writing long literal numbers, it’s harder on the eye to figure out how some numbers are grouped together, for example with groups of thousands, of words, etc. By allowing you to place underscore in number literals, it’s easier to spot those groups:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=underscore_in_number_example,indent=0]
----

== Number type suffixes

We can force a number (including binary, octals and hexadecimals) to have a specific type by giving a suffix (see table below), either uppercase or lowercase.

[cols="1,2" options="header"]
|====
|Type
|Suffix

|BigInteger
|`G` or `g`

|Long
|`L` or `l`

|Integer
|`I` or `i`

|BigDecimal
|`G` or `g`

|Double
|`D` or `d`

|Float
|`F` or `f`
|====

Examples:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=number_type_suffixes_example,indent=0]
----

== Math operations

Although <<{core-operators}#groovy-operators,operators>> are covered in more detail elsewhere, it's important to discuss the behavior of math operations
and what their resulting types are.

Division and power binary operations aside (covered below),

* binary operations between `byte`, `char`, `short` and `int` result in `int`
* binary operations involving `long` with `byte`, `char`, `short` and `int` result in `long`
* binary operations involving `BigInteger` and any other integral type result in `BigInteger`
* binary operations involving `BigDecimal` with `byte`, `char`, `short`, `int` and `BigInteger` result in `BigDecimal`
* binary operations between `float`, `double` and `BigDecimal` result in `double`
* binary operations between two `BigDecimal` result in `BigDecimal`

The following table summarizes those rules:

[cols="10" options="header"]
|====
|
| byte
| char
| short
| int
| long
| BigInteger
| float
| double
| BigDecimal

| *byte*
| int
| int
| int
| int
| long
| BigInteger
| double
| double
| BigDecimal

| *char*
|
| int
| int
| int
| long
| BigInteger
| double
| double
| BigDecimal

| *short*
|
|
| int
| int
| long
| BigInteger
| double
| double
| BigDecimal

| *int*
|
|
|
| int
| long
| BigInteger
| double
| double
| BigDecimal

| *long*
|
|
|
|
| long
| BigInteger
| double
| double
| BigDecimal

| *BigInteger*
|
|
|
|
|
| BigInteger
| double
| double
| BigDecimal

| *float*
|
|
|
|
|
|
| double
| double
| double

| *double*
|
|
|
|
|
|
|
| double
| double

| *BigDecimal*
|
|
|
|
|
|
|
|
| BigDecimal
|====

[NOTE]
Thanks to Groovy's operator overloading, the usual arithmetic operators work as well with `BigInteger` and `BigDecimal`,
unlike in Java where you have to use explicit methods for operating on those numbers.

[[integer_division]]
=== The case of the division operator

The division operators `/` (and `/=` for division and assignment) produce a `double` result
if either operand is a `float` or `double`, and a `BigDecimal` result otherwise
(when both operands are any combination of an integral type `short`, `char`, `byte`, `int`, `long`,
`BigInteger` or `BigDecimal`).

Under static type checking, the inferred type of a division follows the same rule from the
static types of the operands. An operand typed as `Number` may hold a `Float` or `Double` at
runtime as well as any of the other types, so a division involving one is inferred as `Number`.

`BigDecimal` division is performed with the `divide()` method if the division is exact
(i.e. yielding a result that can be represented within the bounds of the same precision and scale),
or using a `MathContext` with a http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#precision()[precision]
of the maximum of the two operands' precision plus an extra precision of 10,
and a http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#scale()[scale]
of the maximum of 10 and the maximum of the operands' scale.

[NOTE]
For integer division like in Java, you should use the `intdiv()` method,
as Groovy doesn't provide a dedicated integer division operator symbol.

[[power_operator]]
=== The case of the power operator

The power operation is represented by the `**` operator, with two parameters: the base and the exponent.
The result of the power operation depends on its operands, and the result of the operation
(in particular if the result can be represented as an integral value).

The following rules are used by Groovy's power operation to determine the resulting type:

* If the exponent is a decimal value
** if the result can be represented as an `Integer`, then return an `Integer`
** else if the result can be represented as a `Long`, then return a `Long`
** otherwise return a `Double`
* If the exponent is an integral value
** if the exponent is strictly negative, then return an `Integer`, `Long` or `Double` if the result value fits in that type
** if the exponent is positive or zero
*** if the base is a `BigDecimal`, then return a `BigDecimal` result value
*** if the base is a `BigInteger`, then return a `BigInteger` result value
*** if the base is an `Integer`, then return an `Integer` if the result value fits in it, otherwise a `BigInteger`
*** if the base is a `Long`, then return a `Long` if the result value fits in it, otherwise a `BigInteger`

We can illustrate those rules with a few examples:

[source,groovy]
----
include::../test/SyntaxTest.groovy[tags=number_power,indent=0]
----

---

### Src Spec Doc Contributors (`src/spec/doc/contributors.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Contributors

The Groovy team would like to thank the contributors of this documentation (in alphabetical order of last/surname):

* https://github.com/mojavelinux[Dan Allen]
* https://github.com/and-dmitry[Dmitry Andreychuk]
* http://hamletdarcy.blogspot.fr/[Hamlet D'Arcy]
* https://github.com/anshbansal[Aseem Bansal]
* https://github.com/bura[Andrey Bloschetsov]
* https://github.com/JBrownVisualSpection[J Brown]
* https://github.com/jeffbrown[Jeff Scott Brown]
* http://twitter.com/CedricChampeau[Cédric Champeau]
* https://github.com/tobia[Tobia Conforto]
* https://github.com/ddimtirov[Dimitar Dimitrov]
* http://twitter.com/werdnagreb[Andrew Eisenberg]
* https://github.com/erdi[Marcin Erdmann]
* https://github.com/christoph-frick[Christoph Frick]
* http://twitter.com/marioggar[Mario García]
* https://github.com/davidmichaelkarr[David Michael Karr]
* http://twitter.com/paulk_asert[Paul King]
* http://twitter.com/glaforge[Guillaume Laforge]
* http://twitter.com/pledbrook[Peter Ledbrook]
* http://grantmcconnaughey.github.io/[Grant McConnaughey]
* https://github.com/eric-milles[Eric Milles]
* https://github.com/dnahodil[David Nahodil]
* https://github.com/jnorthr[James Northrop]
* https://github.com/marcpa00[Marc Paquette]
* https://github.com/michaelss[Michael Schuenck]
* https://github.com/PascalSchumacher[Pascal Schumacher]
* https://github.com/shils[Shil Sinha]
* https://github.com/stavytskyi[Maksym Stavytskyi]
* https://twitter.com/asteingr[André Steingreß]
* https://twitter.com/daniel_sun[Daniel Sun]
* https://github.com/EPadronU[Edinson Padrón Urdaneta]
* https://github.com/keeganwitt[Keegan Witt]

---

### Src Spec Doc Core Async Await (`src/spec/doc/core-async-await.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Async/Await (Incubating)

[[async-intro]]
== Introduction

Groovy provides native `async`/`await` support, enabling developers to write
concurrent code in a sequential, readable style. Rather than dealing with
callbacks, `CompletableFuture` chains, or manual thread management, you express
concurrency with two constructs:

* **`async { ... }`** — start a closure on a background thread, returning an `Awaitable`
* **`await expr`** — block until an asynchronous result is available

On JDK 21+, async tasks automatically leverage
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.html#ofVirtual()[virtual threads]
for optimal scalability. On JDK 17–20, a cached thread pool is used as a
fallback.

The examples throughout this guide use an online multiplayer card game as a
running theme — dealing hands, racing for the fastest play, streaming cards,
and managing tournament rounds.

[[async-getting-started]]
== Getting Started

=== Your first async/await

`async { ... }` starts work immediately on a background thread and returns an
`Awaitable`. Use `await` to collect the result:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=draw_card,indent=0]
----

=== Exception handling

`await` unwraps `CompletionException` and `ExecutionException` automatically.
Standard `try`/`catch` works exactly as with synchronous code:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=exception_handling,indent=0]
----

=== CompletableFuture interop

`await` works directly with `CompletableFuture`, `CompletionStage`, and `Future`
from Java libraries:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=cf_interop,indent=0]
----

[[async-parallel]]
== Running Tasks in Parallel

The real power of async/await appears when you need to run several tasks
concurrently and coordinate their results.

=== Waiting for all: `Awaitable.all()`

Deal cards to multiple players at the same time and wait for all hands:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=deal_hands,indent=0]
----

Multi-argument `await` is syntactic sugar for `Awaitable.all()`:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=multi_arg_await,indent=0]
----

=== Racing: `Awaitable.any()`

Like JavaScript's `Promise.race()` — settles as soon as the first task
settles, returning its result _or_ propagating its error. A task that fails
first therefore fails the whole `any`, even if a later task would have
succeeded (use `first` if you want the first _success_ instead). Useful for
fallback patterns or latency-sensitive code:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=fastest_server,indent=0]
----

=== First success: `Awaitable.first()`

Like JavaScript's `Promise.any()` — returns the first _successful_ result,
silently ignoring individual failures. Only fails when every task fails:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=first_success,indent=0]
----

=== Inspecting all outcomes: `Awaitable.allSettled()`

Waits for all tasks to finish (succeed or fail) without throwing. Returns an
`AwaitResult` list where each entry has `success`, `value`, and `error` fields:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=all_settled,indent=0]
----

=== Combinator summary

[cols="1,2,2,2", options="header"]
|===
| Combinator | Completes when | On failure | Use case

| `Awaitable.all`
| All succeed
| Fails immediately on first failure (fail-fast)
| Gather results from independent tasks

| `Awaitable.allSettled`
| All complete (success or fail)
| Never throws; failures captured in `AwaitResult` list
| Inspect every outcome, e.g. partial-success reporting

| `Awaitable.any`
| First task settles (success or failure)
| Propagates the first settlement's result or error (JS `Promise.race`)
| Latency-sensitive races, fastest-response wins

| `Awaitable.first`
| First task succeeds, or all fail
| Throws only when every source fails (aggregate error)
| Hedged requests, graceful degradation with fallbacks
|===

NOTE: `all` and `allSettled` accept an empty source list and complete with an
empty result. `any` and `first` require at least one source (and reject `null`
elements), throwing `IllegalArgumentException` otherwise — a "race" or "first
success" with no participants has no meaningful result.

[[async-generators]]
== Generators and Streaming

=== Producing values with `yield return`

An `async` closure containing `yield return` becomes a _generator_ — it lazily
produces a sequence of values. The generator runs on a background thread and
blocks on each `yield return` until the consumer is ready, providing natural
back-pressure:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=deck_generator,indent=0]
----

Generators return a standard `Iterable`, so regular `for` loops and Groovy
collection methods (`collect`, `findAll`, `take`, etc.) work out of the box:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=generator_regular_for,indent=0]
----

include::_core-async-channels.adoc[]

[[async-defer]]
== Deferred Cleanup with `defer`

The `defer` keyword schedules a cleanup action to run when the enclosing
`async` closure completes, regardless of success or failure. Multiple
deferred actions execute in LIFO order — last registered, first to run —
making it natural to pair resource acquisition with cleanup:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=defer_basic,indent=0]
----

Deferred actions always run, even when an exception occurs:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=defer_exception,indent=0]
----

If a deferred action returns an `Awaitable` or `Future`, the result is awaited
before the next deferred action runs, ensuring orderly cleanup of asynchronous
resources.

[[async-structured]]
== Structured Concurrency

Structured concurrency ensures that concurrent tasks have clear ownership and
bounded lifetimes — no orphaned background work, no silent failures leaking
across your application. This idea is gaining momentum across the industry
(Java's https://openjdk.org/jeps/453[JEP 453], Go's `errgroup`, Kotlin's
coroutine scopes) because it makes concurrent code easier to reason about,
test, and debug. Groovy's `AsyncScope` provides these guarantees today, even
on JDK versions before Project Loom's `StructuredTaskScope` ships as a final API.

`AsyncScope` binds the lifetime of child tasks to a scope. When the scope
exits, all children are guaranteed complete (or cancelled). This prevents
orphaned tasks and silent failures:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=structured_concurrency,indent=0]
----

By default, the scope uses **fail-fast** semantics — if any child fails,
all siblings are cancelled immediately:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=scope_fail_fast,indent=0]
----

The scope waits for every child to finish, even without explicit `await` calls:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=scope_waits,indent=0]
----

On JDK 25+, scope tracking uses `ScopedValue` for optimal virtual thread
performance (no per-thread storage, automatic inheritance). On JDK 17–24,
a `ThreadLocal` fallback is used transparently.

[[async-advanced]]
== Advanced Topics

[[async-for-await]]
=== Consuming with `for await`

`for await` iterates over any async source. For generators and plain collections,
it works identically to a regular `for` loop:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=for_await_generator,indent=0]
----

The key value of `for await` is with **reactive types** (Reactor `Flux`, RxJava
`Observable`, `java.util.concurrent.Flow.Publisher`) where it automatically
converts the source to a blocking iterable via the adapter SPI. Without
`for await`, you would need to call the conversion manually (e.g.,
`flux.toIterable()`). For generators and plain collections, a regular `for`
loop works identically.

The JDK's `Flow.Publisher` is supported out of the box — no adapter module
needed. This means streams exposed by built-in sources such as
`Agent.changes()` (see <<{core-concurrent-actors}#actors-agent,Agent>>) and `BroadcastChannel.asPublisher()`
(see xref:async-broadcast-channel[]), or any third-party publisher using the JDK
interfaces, compose directly with `for await` and `await`:

[source,groovy]
----
import groovy.concurrent.Agent

def agent = Agent.create(0)
try {
    async {
        3.times { agent.send { it + 1 } }
        agent.shutdown()
    }
    for await (v in agent.changes()) {
        println "value is now $v"
    }
} finally {
    agent.shutdown()
}
----

[[async-timeouts]]
=== Timeouts and Delays

Apply a deadline to any task. If it doesn't complete in time, a
`TimeoutException` is thrown:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=timeout,indent=0]
----

Or use a fallback value instead of throwing:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=timeout_fallback,indent=0]
----

`Awaitable.delay()` pauses without blocking a thread:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=delay,indent=0]
----

[[async-adapters]]
=== Framework Adapters

`await` natively understands `Awaitable`, `CompletableFuture`, `CompletionStage`,
and `Future`. `for await` natively understands `java.util.concurrent.Flow.Publisher`
in addition to regular `Iterable` sources. Third-party async types can be
supported by implementing the `AwaitableAdapter` SPI and registering it via
`META-INF/services/groovy.concurrent.AwaitableAdapter`.

Drop-in adapter modules are provided for:

* **`groovy-reactor`** — `await` on `Mono`, `for await` over `Flux`
* **`groovy-rxjava`** — `await` on `Single`/`Maybe`/`Completable`,
  `for await` over `Observable`/`Flowable`

For example, without the adapter you must manually convert RxJava types:

[source,groovy]
----
// Without groovy-rxjava — manual conversion
def result = Single.just('hello').toCompletionStage().toCompletableFuture().join()
----

With `groovy-rxjava` on the classpath, the conversion is transparent:

[source,groovy]
----
// With groovy-rxjava — adapter handles the plumbing
def result = await Awaitable.from(Single.just('hello'))
----

[[async-executor]]
=== Executor Configuration

By default, `async` uses:

* **JDK 21+**: a virtual-thread-per-task executor
* **JDK 17–20**: a cached daemon thread pool (max 256 threads, configurable
  via `groovy.async.parallelism` system property)

You can override the executor:

[source,groovy]
----
import org.apache.groovy.runtime.async.AsyncSupport
import java.util.concurrent.Executors

AsyncSupport.setExecutor(Executors.newFixedThreadPool(4))
AsyncSupport.setExecutor(null)  // restore platform default
// or equivalently:
AsyncSupport.resetExecutor()
----

[[async-jdk-integration]]
=== Integration with JDK Classes

`await` works with any JDK API that returns a `CompletableFuture`, `CompletionStage`,
or `Future`. This means you can combine process execution, asynchronous file I/O,
and HTTP calls in a single `async` block — all running concurrently:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=jdk_integration,indent=0]
----

Task 3 uses Groovy's `HttpBuilder` (from `groovy-http-builder`), which wraps
JDK `HttpClient` with a concise DSL. For lower-level control, you can also use
`HttpClient` directly:

[source,groovy]
----
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse

def webContent = async {
    def client = HttpClient.newHttpClient()
    def req = HttpRequest.newBuilder()
        .uri(URI.create('https://api.example.com/data'))
        .build()
    def resp = await client.sendAsync(req, HttpResponse.BodyHandlers.ofString())
    resp.body()
}
----

Key JDK classes that work with `await` out of the box:

[cols="2,2", options="header"]
|===
| JDK class | Method returning async result

| `Process`
| `onExit()` → `CompletableFuture<Process>`

| `HttpClient`
| `sendAsync(...)` → `CompletableFuture<HttpResponse<T>>`

| `Path` (via `groovy-nio`)
| `getTextAsync()`, `getBytesAsync()`, `writeAsync(...)` → `CompletableFuture`

| `AsynchronousFileChannel`
| `read(...)`, `write(...)`, `lock(...)` → `Future<Integer>` / `Future<FileLock>`

| `CompletableFuture`
| `supplyAsync(...)`, `allOf(...)`, `anyOf(...)` → `CompletableFuture<T>`
|===

[[async-closure-factories]]
=== Async Closure Factories

Because `async { ... }` is just an expression that returns an `Awaitable`, you
can wrap it in an ordinary method or closure to create a reusable factory:

[source,groovy]
----
include::../test/AsyncAwaitSpecTest.groovy[tags=closure_factory,indent=0]
----

This is a natural way to build reusable async building blocks without any
special framework support.

[[async-best-practices]]
== Best Practices

[[async-prefer-values]]
=== Prefer returning values over mutating shared state

Async closures run on separate threads. Mutating shared variables from multiple
closures is a race condition:

[source,groovy]
----
// UNSAFE — shared mutation without synchronization
var count = 0
def tasks = (1..100).collect { async { count++ } }
tasks.each { await it }
// count may not be 100!
----

Instead, return values and collect results:

[source,groovy]
----
// SAFE — no shared mutation
def tasks = (1..100).collect { n -> async { n } }
def results = await Awaitable.all(*tasks)
assert results.sum() == 5050
----

When shared mutable state is unavoidable, use the appropriate concurrency-aware
type, e.g. `AtomicInteger` for a shared counter, or thread-safe types from
`java.util.concurrent` for players concurrently drawing cards from a shared deck.

[[async-choose-right-tool]]
=== Choosing the right tool

[cols="2,3", options="header"]
|===
| Feature | Use when...

| `async`/`await`
| You have sequential steps involving I/O or blocking work and want code that reads top-to-bottom.

| `Awaitable.all` / `any` / `first`
| You need to launch independent tasks and collect all results, race them, or take the first success.

| `yield return` / `for await`
| You're producing or consuming a stream of values — paginated APIs, card dealing, log tailing.

| `defer`
| You acquire resources at different points and want guaranteed cleanup without nested `try`/`finally`.

| `AsyncChannel`
| Two or more tasks need to communicate — producer/consumer, fan-out/fan-in, or hand-off.

| `AsyncScope`
| You want child task lifetimes tied to a scope with automatic cancellation on failure.

| Framework adapters
| You're already using Reactor or RxJava and want `await` / `for await` to work with their types.
|===

[[async-summary]]
== Quick Reference

[cols="1,3"]
|===
| Construct | Description

| `async { ... }`
| Start a closure on a background thread. Returns `Awaitable` (or `Iterable` for generators).

| `await expr`
| Block until the result is available. Rethrows the original exception.

| `await(a, b, c)`
| Wait for all — syntactic sugar for `await Awaitable.all(a, b, c)`.

| `yield return expr`
| Produce a value from an async generator. Consumer blocks until ready.

| `for await (x in src)`
| Iterate over an async source (generator, channel, Flux, Observable, etc.).

| `defer expr`
| Schedule a cleanup action (LIFO order) inside an `async` closure.

| `AsyncChannel.create(n)`
| Create a buffered (or unbuffered) channel for inter-task communication.

| `ChannelSelect.after(ms)`
| Timer offer: a `ChannelSelect` branch that re-arms each round and commits with the `Instant` it fired.

| `AsyncChannel.after(ms)`
| Timer channel: delivers the `Instant` it fired, then closes. A fixed deadline as a `ChannelSelect` branch.

| `AsyncScope.withScope { ... }`
| Structured concurrency — all children complete (or are cancelled) on scope exit.

| `Awaitable.orTimeoutMillis`
| Apply a deadline. Throws `TimeoutException` if the task exceeds it.

| `Awaitable.completeOnTimeoutMillis`
| Apply a deadline with a fallback value instead of throwing.

| `Awaitable.delay(ms)`
| Non-blocking pause.
|===

All keywords (`async`, `await`, `defer`) are contextual — they can still be
used as variable or method names in existing code.

include::_core-gpars-migration.adoc[]

include::../../../subprojects/groovy-macro-library/src/spec/doc/_monadic-comprehensions.adoc[leveloffset=+1]

---

### Src Spec Doc Core Closures (`src/spec/doc/core-closures.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Closures

:lambdas: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html[lambda expressions in Java 8]

This chapter covers Groovy Closures. A closure in Groovy is an open, anonymous, block of code that can take arguments,
return a value and be assigned to a variable. A closure may reference variables declared in its surrounding scope. In
opposition to the formal definition of a closure, `Closure` in the Groovy language can also contain free variables which
are defined outside of its surrounding scope. While breaking the formal concept of a closure, it offers a variety of
advantages which are described in this chapter.

== Syntax
=== Defining a closure

A closure definition follows this syntax:

[source,groovy]
-----------------------------------
{ [closureParameters -> ] statements }
-----------------------------------

Where `+[closureParameters->]+` is an optional comma-delimited list of
parameters, and statements are 0 or more Groovy statements. The parameters
look similar to a method parameter list, and these parameters may be
typed or untyped.

When a parameter list is specified, the `+->+` character
is required and serves to separate the arguments from the closure body.
The _statements_ portion consists of 0, 1, or many Groovy statements.

Some examples of valid closure definitions:

[source,groovy]
-----------------------------------------------------------
include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_1,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_1bis,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_2,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_3,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_4,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_5,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_syntax_6,indent=0]
-----------------------------------------------------------
<1> A closure referencing a variable named `item`
<2> It is possible to explicitly separate closure parameters from code by adding an arrow (`+->+`)
<3> A closure using an implicit parameter (`it`)
<4> An alternative version where `it` is an explicit parameter
<5> In that case it is often better to use an explicit name for the parameter
<6> A closure accepting two typed parameters
<7> A closure can contain multiple statements

[[closure-as-object]]
=== Closures as an object

A closure is an instance of the `groovy.lang.Closure` class, making it assignable to a variable or a field as any
other variable, despite being a block of code:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_is_an_instance_of_Closure,indent=0]
----
<1> You can assign a closure to a variable, and it is an instance of `groovy.lang.Closure`
<2> If not using `def` or `var`, use `groovy.lang.Closure` as the type
<3> Optionally, you can specify the return type of the closure by using the generic type of `groovy.lang.Closure`

=== Calling a closure

A closure, as an anonymous block of code, can be called like any other method. If you define a closure which takes
no argument like this:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_call_1,indent=0]
----

Then the code inside the closure will only be executed when you _call_ the closure, which can be done by using the
variable as if it was a regular method:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_call_1_direct,indent=0]
----

Alternatively, you can be explicit and use the `call` method:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_call_1_explicit,indent=0]
----

The principle is the same if the closure accepts arguments:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_call_2,indent=0]
----
<1> define a closure which accepts an `int` as a parameter
<2> it can be called directly
<3> or using the `call` method
<4> same goes for a closure with an implicit argument (`it`)
<5> which can be called directly using `(arg)`
<6> or using `call`

Unlike a method, a closure *always* returns a value when called. The next section discusses how to declare closure arguments, when to use them and what is the <<implicit-it,implicit
"it" parameter>>.

== Parameters

=== Normal parameters

Parameters of closures follow the same principle as parameters of regular methods:

* an optional type
* a name
* an optional default value

Parameters are separated with commas:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_param_declaration,indent=0]
----

[[implicit-it]]
=== Implicit parameter

When a closure does not explicitly define a parameter list (using `+->+`), a closure *always* defines an implicit
parameter, named `it`. This means that this code:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=implicit_it,indent=0]
----

is strictly equivalent to this one:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=implicit_it_equiv,indent=0]
----

If you want to declare a closure which accepts no argument and must be restricted to calls without arguments,
then you *must* declare it with an explicit empty argument list:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_no_arg_def,indent=0]

include::../test/ClosuresSpecTest.groovy[tags=closure_no_arg_fail,indent=0]
----

=== Varargs

It is possible for a closure to declare variable arguments like any other method. _Vargs_ methods are methods that
can accept a variable number of arguments if the last parameter is of variable length (or an array) like in the next
examples:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_vargs,indent=0]
----
<1> A closure accepting a variable number of strings as first parameter
<2> It may be called using any number of arguments *without* having to explicitly wrap them into an array
<3> The same behavior is directly available if the _args_ parameter is declared as an array
<4> As long as the *last* parameter is an array or an explicit vargs type

== Delegation strategy

=== Groovy closures vs lambda expressions

Groovy defines closures as <<closure-as-object, instances of the Closure class>>. It makes it very different from
{lambdas}. Delegation is a
key concept in Groovy closures which has no equivalent in lambdas. The ability to _change the delegate_ or _change the
delegation strategy_ of closures make it possible to design beautiful domain specific languages (DSLs) in Groovy.

[[closure-owner]]
=== Owner, delegate and this

To understand the concept of delegate, we must first explain the meaning of `this` inside a closure. A closure actually
defines 3 distinct things:

- `this` corresponds to the _enclosing class_ where the closure is defined
- `owner` corresponds to the _enclosing object_ where the closure is defined, which may be either a class or a closure
- `delegate` corresponds to a third party object where methods calls or properties are resolved whenever the receiver of
the message is not defined

[[closure-this]]
==== The meaning of this

In a closure, calling `getThisObject` will return the enclosing class where the closure is defined. It is equivalent to
using an explicit `this`:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_this,indent=0]
----
<1> a closure is defined inside the `Enclosing` class, and returns `getThisObject`
<2> calling the closure will return the instance of `Enclosing` where the closure is defined
<3> in general, you will just want to use the shortcut `this` notation
<4> and it returns *exactly* the same object
<5> if the closure is defined in an inner class
<6> `this` in the closure *will* return the inner class, not the top-level one
<7> in case of nested closures, like here `cl` being defined inside the scope of `nestedClosures`
<8> then `this` corresponds to the closest outer class, not the enclosing closure!

It is of course possible to call methods from the enclosing class this way:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_this_call,indent=0]
----
<1> the closure calls `toString` on `this`, which will actually call the `toString` method on the enclosing object,
that is to say the `Person` instance

==== Owner of a closure

The owner of a closure is very similar to the definition of <<closure-this,this in a closure>> with a subtle difference:
it will return the direct enclosing object, be it a closure or a class:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_owner,indent=0]
----
<1> a closure is defined inside the `Enclosing` class, and returns `getOwner`
<2> calling the closure will return the instance of `Enclosing` where the closure is defined
<3> in general, you will just want to use the shortcut `owner` notation
<4> and it returns *exactly* the same object
<5> if the closure is defined in an inner class
<6> `owner` in the closure *will* return the inner class, not the top-level one
<7> but in case of nested closures, like here `cl` being defined inside the scope of `nestedClosures`
<8> then `owner` corresponds to the enclosing closure, hence a different object from `this`!

==== Delegate of a closure

The delegate of a closure can be accessed by using the `delegate` property or calling the `getDelegate` method. It is a
powerful concept for building domain specific languages in Groovy. While <<closure-this,this>> and <<closure-owner,owner>>
refer to the lexical scope of a closure, the delegate is a user defined object that a closure will use. By default, the
delegate is set to `owner`:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=delegate_is_owner,indent=0]
----
<1> you can get the delegate of a closure calling the `getDelegate` method
<2> or using the `delegate` property
<3> both return the same object
<4> which is the enclosing class or closure
<5> in particular in case of nested closures
<6> `delegate` will correspond to the `owner`

The delegate of a closure can be changed to *any object*. Let's illustrate this by creating two classes which are not
subclasses of each other but both define a property called `name`:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=change_delegate_classes,indent=0]
----

Then let's define a closure which fetches the `name` property on the delegate:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=change_delegate_closure,indent=0]
----

Then by changing the delegate of the closure, you can see that the target object will change:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=change_delegate_asserts,indent=0]
----

At this point, the behavior is not different from having a `target` variable defined in the lexical scope of the closure:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=delegate_alernative,indent=0]
----

However, there are major differences:

* in the last example, _target_ is a local variable referenced from within the closure
* the delegate can be used transparently, that is to say without prefixing method calls with `delegate.` as explained
in the next paragraph.

==== Delegation strategy

Whenever, in a closure, a property is accessed without explicitly setting a receiver object, then a delegation strategy
is involved:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=delegation_strategy_intro,indent=0]
----
<1> `name` is not referencing a variable in the lexical scope of the closure
<2> we can change the delegate of the closure to be an instance of `Person`
<3> and the method call will succeed

The reason this code works is that the `name` property will be resolved transparently on the `delegate` object! This is
a very powerful way to resolve properties or method calls inside closures. There's no need to set an explicit `delegate.`
receiver: the call will be made because the default delegation strategy of the closure makes it so. A closure actually
defines multiple resolution strategies that you can choose:

* `Closure.OWNER_FIRST` is the *default strategy*. If a property/method exists on the *owner*, then it will be called on
the owner. If not, then the *delegate* is used.
* `Closure.DELEGATE_FIRST` reverses the logic: the *delegate* is used first, then the *owner*
* `Closure.OWNER_ONLY` will only resolve the property/method lookup on the owner: the delegate will be ignored.
* `Closure.DELEGATE_ONLY` will only resolve the property/method lookup on the delegate: the owner will be ignored.
* `Closure.TO_SELF` can be used by developers who need advanced meta-programming techniques and wish to implement a
 custom resolution strategy: the resolution will not be made on the owner or the delegate but only on the closure class
 itself. It makes only sense to use this if you implement your own subclass of `Closure`.

Let's illustrate the default "owner first" strategy with this code:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_owner_first,indent=0]
----
<1> for the illustration, we define a closure member which references "name"
<2> both the `Person` and the `Thing` class define a `name` property
<3> Using the default strategy, the `name` property is resolved on the owner first
<4> so if we change the `delegate` to `t` which is an instance of `Thing`
<5> there is no change in the result: `name` is first resolved on the `owner` of the closure

However, it is possible to change the resolution strategy of the closure:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_delegate_first,indent=0]
----

By changing the `resolveStrategy`, we are modifying the way Groovy will resolve the "implicit this" references: in this
case, `name` will first be looked in the delegate, then if not found, on the owner. Since `name` is defined in the
delegate, an instance of `Thing`, then this value is used.

The difference between "delegate first" and "delegate only" or "owner first" and "owner only" can be illustrated if one
of the delegate (resp. owner) does *not* have such a method or property:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=delegate_only,indent=0]
----
<1> for "owner first" it doesn't matter what the delegate is
<2> for "delegate only" having `p` as the delegate succeeds
<3> for "delegate only" having `t` as the delegate fails

In this example, we define two classes which both have a `name` property but only the `Person` class declares an `age`.
The `Person` class also declares a closure which references `age`. We can change the default resolution strategy from
"owner first" to "delegate only". Since the owner of the closure is the `Person` class, then we can check that if the
delegate is an instance of `Person`, calling the closure is successful, but if we call it with a delegate being an
instance of `Thing`, it fails with a `groovy.lang.MissingPropertyException`. Despite the closure being defined inside
the `Person` class, the owner is not used.

NOTE: A comprehensive explanation about how to use this feature to develop DSLs can be found in a
link:core-domain-specific-languages.html[dedicated section of the manual].

==== Delegation strategy in the presence of metaprogramming

When describing the "owner first" delegation strategy we spoke
about using a property/method from the owner if it "_existed_" otherwise
using the respective property/method from the delegate. And a similar
story for "delegate first" but in reverse. Instead of using the word
"_existed_", it would have been more accurate to use the wording "_handled_".
That means that for "owner first", if the property/method exists in
the owner, or it has a propertyMissing/methodMissing hook, then the owner
will handle the member access.

We can see this in action with a slightly altered version of our previous example:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=delegate_only_prop_missing,indent=0]
----

In this example, even though our instance of the `Thing` class (our delegate for the last use of `cl`) has no `age` property,
the fact that it handles the missing property via its `propertyMissing` hook,
means that `age` will be `-1`.

== Closures in GStrings

Take the following code:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=gstring_eager_intro,indent=0]
----

The code behaves as you would expect, but what happens if you add:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=gstring_eager_outro,indent=0]
----

You will see that the assert fails! There are two reasons for this:

* a GString only evaluates lazily the `toString` representation of values
* the syntax `${x}` in a GString does *not* represent a closure but an *expression* to `$x`, evaluated when the GString
is created.

In our example, the `GString` is created with an expression referencing `x`. When the `GString` is created, the *value*
of `x` is 1, so the `GString` is created with a value of 1. When the assert is triggered, the `GString` is evaluated
and 1 is converted to a `String` using `toString`. When we change `x` to 2, we did change the value of `x`, but it is
a different object, and the `GString` still references the old one.

TIP: A `GString` will only change its `toString` representation if the values it references are mutating. If the references
change, nothing will happen.

If you need a real closure in a GString and for example enforce lazy evaluation of variables, you need to use the
alternate syntax `${-> x}` like in the fixed example:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=gstring_lazy,indent=0]
----

And let's illustrate how it differs from mutation with this code:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=gstring_mutation,indent=0]
----
<1> the `Person` class has a `toString` method returning the `name` property
<2> we create a first `Person` named _Sam_
<3> we create another `Person` named _Lucy_
<4> the `p` variable is set to `Sam`
<5> and a closure is created, referencing the value of `p`, that is to say _Sam_
<6> so when we evaluate the string, it returns _Sam_
<7> if we change `p` to _Lucy_
<8> the string still evaluates to _Sam_ because it was the *value* of `p` when the `GString` was created
<9> so if we mutate _Sam_ to change the name to _Lucy_
<10> this time the `GString` is correctly mutated

So if you don't want to rely on mutating objects or wrapping objects, you *must* use closures in `GString` by explicitly
declaring an empty argument list:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=gstring_no_mutation,indent=0]
----

== Closure coercion

Closures can be converted into interfaces or single-abstract method types. Please refer to
link:core-semantics.html#closure-coercion[this section of the manual] for a complete description.

== Functional programming

Closures, like {lambdas} are at the core of the functional programming paradigm in Groovy. Some functional programming
operations on functions are available directly on the `Closure` class, like illustrated in this section.

=== Currying

In Groovy, currying refers to the concept of partial application. It does *not* correspond to the real concept of currying
in functional programming because of the different scoping rules that Groovy applies on closures. Currying in Groovy will
let you set the value of one parameter of a closure, and it will return a new closure accepting one less argument.

==== Left currying

Left currying is the fact of setting the left-most parameter of a closure, like in this example:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=left_curry,indent=0]
----
<1> the `nCopies` closure defines two parameters
<2> `curry` will set the first parameter to `2`, creating a new closure (function) which accepts a single `String`
<3> so the new function call be called with only a `String`
<4> and it is equivalent to calling `nCopies` with two parameters

==== Right currying

Similarly to left currying, it is possible to set the right-most parameter of a closure:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=right_curry,indent=0]
----
<1> the `nCopies` closure defines two parameters
<2> `rcurry` will set the last parameter to `bla`, creating a new closure (function) which accepts a single `int`
<3> so the new function call be called with only an `int`
<4> and it is equivalent to calling `nCopies` with two parameters

==== Index based currying

In case a closure accepts more than 2 parameters, it is possible to set an arbitrary parameter using `ncurry`:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=ncurry,indent=0]
----
<1> the `volume` function defines 3 parameters
<2> `ncurry` will set the second parameter (index = 1) to `2d`, creating a new volume function which accepts length and height
<3> that function is equivalent to calling `volume` omitting the width
<4> it is also possible to set multiple parameters, starting from the specified index
<5> the resulting function accepts as many parameters as the initial one minus the number of parameters set by `ncurry`

==== Currying functional interfaces

When working with `java.util.function` types — for example `BiPredicate`,
`BiFunction` or `BiConsumer` — `Closure.rcurry` is not applicable. Two
sibling utility classes provide right-partial helpers, differing only in
the type returned:

* `org.apache.groovy.util.Lambdas#curryWith` returns a bare
  `Predicate`/`Function`/`Consumer`. Use when the result will flow into
  JDK APIs (e.g. `Stream.filter`, `Optional.map`) or into DGM methods
  that already accept SAM types (e.g. `partitionPoint`, `takeIf`,
  `groupConsecutive`).
* `org.apache.groovy.util.Closures#curryWith` returns a hybrid value
  that is both the SAM type *and* a `Closure`. Use when the result
  should also be usable with DGM methods that accept a `Closure`
  (e.g. `findAll`, `collect`, `each`, `find`, `any`, `every`).

[source,groovy]
----
import static org.apache.groovy.util.Lambdas.curryWith as curryWithSam
import static org.apache.groovy.util.Closures.curryWith as curryWithClosure
import java.util.function.BiPredicate

BiPredicate<Integer, Integer> divisibleBy = (n, d) -> n % d == 0

// Lambdas.curryWith: flows into JDK streams / SAM-accepting DGM
assert [1, 2, 3, 4, 5, 6].stream().filter(curryWithSam(divisibleBy, 2)).toList() == [2, 4, 6]

// Closures.curryWith: flows into Closure-accepting DGM as well
assert [1, 2, 3, 4, 5, 6].findAll(curryWithClosure(divisibleBy, 2)) == [2, 4, 6]
----

In both forms a single allocation is paid per `curryWith` call rather
than per element of the traversal.

`Closures.from(Predicate)` (and the `Function`/`Consumer` overloads)
lifts an existing single-argument SAM into the same hybrid form, useful
when an external API hands you a `Predicate` you want to feed into a
`Closure`-accepting DGM method:

[source,groovy]
----
import static org.apache.groovy.util.Closures.from
import java.util.function.Predicate

Predicate<Integer> isEven = n -> n % 2 == 0
assert [1, 2, 3, 4].findAll(from(isEven)) == [2, 4]
----

Three overloads are provided:

* `curryWith(BiPredicate<T,P>, P) -> Predicate<T>`
* `curryWith(BiFunction<T,P,R>, P) -> Function<T,R>`
* `curryWith(BiConsumer<T,P>, P) -> Consumer<T>`

=== Memoization

Memoization allows the result of the call of a closure to be cached. It is interesting if the computation done by a
function (closure) is slow, but you know that this function is going to be called often with the same arguments. A
typical example is the Fibonacci suite. A naive implementation may look like this:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=naive_fib,indent=0]
----

It is a naive implementation because 'fib' is often called recursively with the same arguments, leading to an exponential
algorithm:

- computing `fib(15)` requires the result of `fib(14)` and `fib(13)`
- computing `fib(14)` requires the result of `fib(13)` and `fib(12)`

Since calls are recursive, you can already see that we will compute the same values again and again, although they could
be cached. This naive implementation can be "fixed" by caching the result of calls using `memoize`:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=memoized_fib,indent=0]
----

WARNING: The cache works *using the actual values of the arguments*. This means that you should be very careful if you use
memoization with something else than primitive or boxed primitive types.

The behavior of the cache can be tweaked using alternate methods:

* `memoizeAtMost` will generate a new closure which caches *at most* _n_ values
* `memoizeAtLeast` will generate a new closure which caches *at least* _n_ values
* `memoizeBetween` will generate a new closure which caches *at least* _n_ values and *at most* _n_ values

The cache used in all memoize variants is an LRU cache.

=== Composition

Closure composition corresponds to the concept of function composition, that is to say creating a new function by
composing two or more functions (chaining calls), as illustrated in this example:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=closure_composition,indent=0]
----

=== Trampoline

Recursive algorithms are often restricted by a physical limit: the maximum stack height. For example, if you call a method
that recursively calls itself too deep, you will eventually receive a `StackOverflowException`.

An approach that helps in those situations is by using `Closure` and its trampoline capability.

Closures are wrapped in a `TrampolineClosure`. Upon calling, a trampolined `Closure` will call the original `Closure` waiting
for its result. If the outcome of the call is another instance of a `TrampolineClosure`, created perhaps as a result
to a call to the `trampoline()` method, the `Closure` will again be invoked. This repetitive invocation of returned
trampolined Closures instances will continue until a value other than a trampolined `Closure` is returned. That value
will become the final result of the trampoline. That way, calls are made serially, rather than filling the stack.

Here’s an example of the use of `trampoline()` to implement the factorial function:

[source,groovy]
----
include::../test/ClosuresSpecTest.groovy[tags=trampoline,indent=0]
----

=== Method pointers

It is often practical to be able to use a regular method as a closure. For example, you might want to use the currying
abilities of a closure, but those are not available to normal methods. In Groovy, you can obtain a closure from any
method with the link:core-operators.html#method-pointer-operator[method pointer operator].

---

### Src Spec Doc Core Concurrent Actors (`src/spec/doc/core-concurrent-actors.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Actors and Agents (Incubating)

[[actors-intro]]
== Introduction

Actors and agents provide thread-safe concurrent state management
through message passing. Instead of protecting shared state with locks,
you send messages to an actor or agent which processes them one at a
time on a dedicated thread. This eliminates data races by design.

Groovy provides two levels of abstraction:

- **Agent** — a thread-safe mutable value updated via functions
- **Actor** — a message-processing entity with flexible dispatch

Both use virtual threads on JDK 21+ for efficient scaling.

[[actors-agent]]
== Agent

An `Agent` wraps a value that can be read by any thread but modified
only through serialized update functions:

[source,groovy]
----
import groovy.concurrent.Agent

def counter = Agent.create(0)
counter.send { it + 1 }
counter.send { it + 1 }
counter.send { it + 1 }

assert await(counter.getAsync()) == 3
----

=== Reading

[source,groovy]
----
// Snapshot read — non-blocking, returns current value
def current = counter.get()

// Consistent read — waits for pending updates to complete
def consistent = await(counter.getAsync())
----

=== Updating

[source,groovy]
----
// Fire-and-forget update
counter.send { it + 1 }

// Update and get new value
def newValue = await(counter.sendAndGet { it * 2 })
----

=== Complex state

Agents work with any value type:

[source,groovy]
----
def inventory = Agent.create([:])

inventory.send { state -> state + [apples: 10] }
inventory.send { state -> state + [bananas: 5] }
inventory.send { state ->
    state.collectEntries { k, v -> [k, v * 2] }
}

assert await(inventory.getAsync()) == [apples: 20, bananas: 10]
----

=== Observing state changes

An agent exposes a `Flow.Publisher<T>` of state transitions via
`changes()`. Each successful update emits the new value to every
subscriber that is already subscribed at the time of the update. The
stream is hot (no replay of prior state), per-subscriber buffered,
and closes with `onComplete` when `shutdown()` is called:

[source,groovy]
----
def agent = Agent.create(0)
try {
    async {
        3.times { agent.send { it + 1 } }
        Thread.sleep(50)
        agent.shutdown()
    }
    def seen = []
    for await (v in agent.changes()) {
        seen << v
    }
    assert seen == [1, 2, 3]
} finally {
    agent.shutdown()
}
----

Slow subscribers drop newly-offered values rather than backpressuring
the agent's update loop — buffered values are still delivered in order,
but the most recent update may be skipped if a subscriber's buffer is
full (default size 256). If `changes()` is first called after
`shutdown()`, the returned publisher is already closed and subscribers
receive `onComplete` immediately.

[[actors-actor]]
== Actor

An `Actor` processes messages from a queue on a dedicated thread.
Two factory methods cover the common patterns:

[[actors-reactor]]
=== Reactor (stateless)

A reactor applies a function to each message. The return value
becomes the reply for `sendAndGet` callers:

[source,groovy]
----
import groovy.concurrent.Actor

def doubler = Actor.reactor { it * 2 }
assert await(doubler.sendAndGet(5)) == 10
assert await(doubler.sendAndGet(21)) == 42
doubler.stop()
----

Reactors are ideal for pure-function message processing — validators,
transformers, calculators:

[source,groovy]
----
def validator = Actor.reactor { msg ->
    if (msg instanceof String && msg.length() > 0) 'valid'
    else 'invalid'
}
----

[[actors-stateful]]
=== Stateful

A stateful actor maintains state across messages. The handler
receives `(state, message)` and returns the new state:

[source,groovy]
----
def counter = Actor.stateful(0) { state, msg ->
    switch (msg) {
        case 'increment': return state + 1
        case 'decrement': return state - 1
        case 'reset':     return 0
        default:          return state
    }
}

counter.send('increment')
counter.send('increment')
counter.send('decrement')
assert await(counter.sendAndGet('increment')) == 2
counter.stop()
----

For `sendAndGet`, the new state is the reply. This makes it easy
to query the current state:

[source,groovy]
----
// Send a no-op message to read the state
def currentState = await(counter.sendAndGet('query'))
----

=== Typed message dispatch

Use pattern matching for rich message protocols:

[source,groovy]
----
def account = Actor.stateful(0.0) { balance, msg ->
    switch (msg) {
        case { it instanceof Map && it.deposit }:
            return balance + msg.deposit
        case { it instanceof Map && it.withdraw }:
            if (msg.withdraw > balance)
                throw new RuntimeException('Insufficient funds')
            return balance - msg.withdraw
        default:
            return balance
    }
}

account.send([deposit: 100])
account.send([withdraw: 30])
def balance = await(account.sendAndGet([deposit: 0]))
assert balance == 70.0
account.stop()
----

[[actors-options]]
== Construction options

Actors take an optional `ActorOptions` configuring the mailbox, the
executor, and a handful of opt-in behaviours. The builder is
value-based; each `with*` method returns a new configuration.

[source,groovy]
----
import groovy.concurrent.Actor
import groovy.concurrent.ActorOptions

def options = ActorOptions.DEFAULTS
    .withBoundedMailbox(1000, ActorOptions.Overflow.BLOCK)

def actor = Actor.reactor(handler, options)
----

=== Bounded mailbox

By default the mailbox is unbounded. For backpressure — or to cap
memory when producers can outrun the actor — configure a capacity and
an overflow policy:

[source,groovy]
----
import groovy.concurrent.ActorOptions.Overflow

// BLOCK — sender blocks until capacity is free
ActorOptions.DEFAULTS.withBoundedMailbox(100, Overflow.BLOCK)

// FAIL — send throws IllegalStateException when the mailbox is full
ActorOptions.DEFAULTS.withBoundedMailbox(100, Overflow.FAIL)

// DROP_NEWEST — the incoming message is silently dropped; for
// sendAndGet, the returned Awaitable binds to IllegalStateException
ActorOptions.DEFAULTS.withBoundedMailbox(100, Overflow.DROP_NEWEST)
----

A handler that calls `ctx.self().send(...)` on a full `BLOCK` mailbox
would deadlock (the handler is the actor's only consumer). The actor
detects this and fails fast with `IllegalStateException` rather than
parking the worker thread.

=== Per-actor executor

Actors default to a shared async executor (virtual threads on
JDK 21+). For workload isolation, hand the actor its own executor:

[source,groovy]
----
import java.util.concurrent.Executors

def pool = Executors.newSingleThreadExecutor()
def actor = Actor.reactor(handler,
    ActorOptions.DEFAULTS.withExecutor(pool))
----

Other options — `withStashBound` and `withCurrentSelf` — are covered
in the <<actors-fsm,FSM section>> where they're directly used.

[[actors-lifecycle]]
== Lifecycle

Both actors and agents support lifecycle management. An actor has a
three-state lifecycle:

[cols="1,1,3"]
|===
|`isActive()` |`isTerminated()` |Meaning

|`true`  |`false` |Accepting new sends and processing them.
|`false` |`false` |Draining — `stop()` was called, no new sends are
accepted, but already-queued messages are still being processed.
|`false` |`true`  |Terminated — the worker thread has exited; all
queued messages are processed and any stashed `sendAndGet` replies
have been rejected.
|===

[source,groovy]
----
def actor = Actor.reactor { it }
assert actor.isActive()
assert !actor.isTerminated()

actor.stop()                                  // flips isActive() to false immediately
assert !actor.isActive()                       // new sends fail from here (a send racing with stop() may still land)

// The worker may still be draining queued messages. Poll for terminated
// when you actually need to be sure the actor has finished shutting down.
while (!actor.isTerminated()) Thread.sleep(10)
assert actor.isTerminated()
----

Actors implement `AutoCloseable`, so they work with
try-with-resources (Groovy or Java):

[source,groovy]
----
Actor.reactor { it * 2 }.withCloseable { actor ->
    assert await(actor.sendAndGet(5)) == 10
}
// actor is stopped
----

[[actors-errors]]
== Error Handling

Exceptions thrown by a handler are delivered to `sendAndGet` callers
through the awaited reply:

[source,groovy]
----
def risky = Actor.reactor { throw new RuntimeException('oops') }
try {
    await(risky.sendAndGet('anything'))
} catch (RuntimeException e) {
    assert e.message == 'oops'
}
risky.stop()
----

Fire-and-forget `send` calls have no reply to carry the exception.
To observe handler failures from those messages — for logging,
metrics, or shutting the actor down — register an `onError` callback:

[source,groovy]
----
def actor = Actor.reactor { msg -> process(msg) }
    .onError { Throwable t, msg ->
        log.warn("handler failed on {}: {}", msg, t.message)
    }
----

The context-aware overload receives an `ActorContext` first, useful
when the callback needs to react beyond logging — for example,
stopping the actor:

[source,groovy]
----
actor.onError { ctx, t, msg -> ctx.self().stop() }
----

Exceptions thrown from inside the `onError` callback itself are
caught and discarded so they cannot destabilise the dispatch loop.

[[actors-fsm]]
== FSM-style actors

A stateful actor models a single behaviour. For multi-phase protocols
— where the actor responds differently depending on which "state" it
is in — three additional capabilities on `ActorContext` cover most of
what you'd reach for from a dedicated FSM library:

- `ctx.become(newHandler)` — swap the active handler at runtime;
  state is preserved across the swap.
- `ctx.stash()` / `ctx.unstashAll()` — defer the current message for
  later replay (typically because it arrived in the wrong phase).
- `ctx.scheduleOnce(msg, delay)` /
  `ctx.scheduleAtFixedRate(msg, initialDelay, interval)` — self-send a
  message after a delay, with a cancellable handle.

These capabilities are only available via the context-aware factory
overloads, which give the handler an `ActorContext` parameter.

=== Swapping behaviour with become

[source,groovy]
----
import groovy.concurrent.Actor
import groovy.concurrent.ActorContext
import groovy.concurrent.StatefulHandler

// Phase A increments by 1; phase B increments by 10.
StatefulHandler phaseB = { ctx, s, m -> s + 10 } as StatefulHandler

def actor = Actor.stateful(0, { ActorContext ctx, int s, m ->
    if (m == 'swap') { ctx.become(phaseB); return s }
    s + 1
} as StatefulHandler)

assert await(actor.sendAndGet('inc'))  == 1
assert await(actor.sendAndGet('swap')) == 1    // state preserved
assert await(actor.sendAndGet('inc'))  == 11   // now phase B
----

The swap takes effect on the next message: the current handler
invocation completes normally (including binding any reply). State is
preserved verbatim; the new handler receives the same state value the
current one would have returned.

=== Deferring messages with stash

When a message arrives while the actor is in the wrong phase, defer
it with `ctx.stash()`. When the phase transitions to one that can
handle it, call `ctx.unstashAll()` to replay all deferred messages in
FIFO order at the head of the mailbox:

[source,groovy]
----
StatefulHandler connected = { ctx, s, m -> "got($m)" } as StatefulHandler

def actor = Actor.stateful('init', { ActorContext ctx, s, m ->
    if (m == 'ready') {
        ctx.become(connected)
        ctx.unstashAll()      // replay anything stashed while not ready
        return s
    }
    ctx.stash()               // any other message is deferred for now
    s
} as StatefulHandler)

def r1 = actor.sendAndGet('A')    // stashed
def r2 = actor.sendAndGet('B')    // stashed
actor.send('ready')               // → connected, then replays A and B
assert await(r1) == 'got(A)'
assert await(r2) == 'got(B)'
----

The stash is unbounded by default.

WARNING: An actor that stashes messages from a source whose volume you
do not control (network input, external clients, untrusted callers)
can grow the stash without limit and exhaust the JVM heap if the phase
transition that would call `unstashAll()` never arrives. For any such
actor, set a bound via `withStashBound` at construction time.

[source,groovy]
----
def options = ActorOptions.DEFAULTS
    .withStashBound(64, ActorOptions.StashOverflow.REJECT)
----

Policies are `FAIL` (throw from `stash()`), `DROP_OLDEST` (evict the
oldest stashed message, binding its `sendAndGet` reply to error), and
`REJECT` (bind the current message's reply to error without stashing
it).

=== Scheduled self-sends

For state timeouts, heartbeats, retries, and periodic work, the
context exposes one-shot and recurring schedules over the shared
async scheduler:

[source,groovy]
----
import java.time.Duration

def actor = Actor.stateful(0, { ActorContext ctx, s, m ->
    if (m == 'start') {
        ctx.scheduleAtFixedRate('tick',
            Duration.ofSeconds(1), Duration.ofSeconds(5))
        return s
    }
    if (m == 'tick') return s + 1
    s
} as StatefulHandler)
----

`scheduleOnce` returns a `Cancellable` so a phase transition can call
off a pending timer:

[source,groovy]
----
def timer = ctx.scheduleOnce('auth-timeout', Duration.ofSeconds(30))
// ... later, when AuthResult arrives:
timer.cancel()
----

`Actor.stop()` cancels every outstanding timer the actor scheduled —
no zombies after shutdown.

=== End-to-end: a connection handshake

A common FSM shape — `disconnected → authenticating → connected` —
combining all three capabilities:

[source,groovy]
----
import groovy.concurrent.Actor
import groovy.concurrent.ActorContext
import groovy.concurrent.StatefulHandler

StatefulHandler disconnected, authenticating, connected

disconnected = { ctx, s, m ->
    if (m == 'connect') { ctx.become(authenticating); return s }
    s
} as StatefulHandler

authenticating = { ctx, s, m ->
    if (m == 'auth-ok') {
        ctx.become(connected)
        ctx.unstashAll()
        return s
    }
    ctx.stash()                // commands arriving during auth are deferred
    s
} as StatefulHandler

connected = { ctx, s, m ->
    // Real connected handlers use s — here we bump an "ops processed"
    // counter to demonstrate that state survives every transition.
    [ops: s.ops + 1]
} as StatefulHandler

def actor = Actor.stateful([ops: 0], disconnected)
actor.send('connect')
def r1 = actor.sendAndGet([cmd: 'read'])    // stashed in authenticating
actor.send('auth-ok')                       // → connected; r1 now processes
assert await(r1) == [ops: 1]                // state preserved across phases
actor.stop()
----

[[actors-vs-agent]]
== Choosing Between Agent and Actor

[cols="1,1,1"]
|===
|Aspect |Agent |Actor

|State
|Single value, updated via function
|Arbitrary, managed by handler

|Messages
|Update functions only
|Any message type with dispatch

|Reply
|`getAsync()` / `sendAndGet(fn)` returns new value
|`sendAndGet(msg)` returns handler result

|Multi-phase behaviour
|—
|`become` / `stash` / scheduled self-sends

|Use case
|Thread-safe counters, caches, accumulators
|State machines, services, typed protocols
|===

Both guarantee sequential message processing — no locks needed.

[[actors-active-object]]
== @ActiveObject / @ActiveMethod

For a more OOP approach, annotate a class with `@ActiveObject` and
its methods with `@ActiveMethod`. The compiler automatically routes
annotated method calls through an internal actor — callers just see
a normal class:

[source,groovy]
----
import groovy.transform.ActiveObject
import groovy.transform.ActiveMethod

@ActiveObject
class Account {
    private double balance = 0

    @ActiveMethod
    void deposit(double amount) { balance += amount }

    @ActiveMethod
    void withdraw(double amount) {
        if (amount > balance) throw new RuntimeException('Insufficient funds')
        balance -= amount
    }

    @ActiveMethod
    double getBalance() { balance }
}

def account = new Account()
account.deposit(100)         // async, serialized, blocks until done
account.deposit(50)
account.withdraw(30)
assert account.getBalance() == 120.0
----

Methods without `@ActiveMethod` run on the caller's thread as normal.

=== Blocking vs non-blocking

By default, `@ActiveMethod` calls block until the actor processes
them. For non-blocking calls, set `blocking = false`:

[source,groovy]
----
@ActiveObject
class Service {
    @ActiveMethod(blocking = false)
    def compute(int x) { x * x }
}

def svc = new Service()
def result = svc.compute(7)  // returns Awaitable immediately
assert await(result) == 49
----

=== Thread safety by annotation

The key benefit: you write normal-looking classes with normal methods.
Thread safety is guaranteed by the annotation — all `@ActiveMethod`
calls are serialized through the actor. No locks, no concurrent
collections, no race conditions.

This also makes the code highly readable for AI tools — the
`@ActiveObject` annotation explicitly declares the concurrency model,
and each `@ActiveMethod` contains pure business logic without
messaging boilerplate.

---

### Src Spec Doc Core Concurrent Dataflow (`src/spec/doc/core-concurrent-dataflow.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Concurrent Dataflow (Incubating)

[[dataflow-intro]]
== Introduction

Dataflow programming lets you express dependencies between concurrent
computations declaratively. Values are bound once and read many times —
the runtime handles ordering automatically. You never need to think
about which thread runs first.

Groovy's dataflow support integrates natively with
<<{core-async-await}#async-intro,async/await>> and the
`Awaitable` API.

[[dataflow-variables]]
== DataflowVariable

A `DataflowVariable` is a single-assignment variable. It starts unbound,
can be written to exactly once, and any thread that reads it before
binding will block until a value is available.

[source,groovy]
----
import groovy.concurrent.DataflowVariable

def x = new DataflowVariable()
def y = new DataflowVariable()
def z = new DataflowVariable()

async {
    z << await(x) + await(y)    // blocks until x and y are bound
}

async { x << 10 }              // bind x — order doesn't matter
async { y << 5 }               // bind y

println "Result: ${await(z)}"  // 15
----

Key properties:

- **Write-once**: calling `bind()` or `<<` a second time throws `IllegalStateException`
- **Implements `Awaitable`**: works with `await`, combinators (`Awaitable.all`), and `then` chaining
- **Thread-safe**: safe to bind from one thread and read from any number of others

=== Error binding

[source,groovy]
----
def v = new DataflowVariable()
v.bindError(new RuntimeException('computation failed'))
// Any thread that awaits v will receive the exception
----

=== Chaining with `then`

[source,groovy]
----
def v = new DataflowVariable()
def doubled = v.then { it * 2 }

async { v << 21 }
assert await(doubled) == 42
----

=== Combining multiple variables

[source,groovy]
----
def a = new DataflowVariable()
def b = new DataflowVariable()
def c = new DataflowVariable()

async { a << 1 }
async { b << 2 }
async { c << 3 }

def results = await(a, b, c)
assert results == [1, 2, 3]
----

[[dataflow-dataflows]]
== Dataflows

`Dataflows` is a convenience class that auto-creates `DataflowVariable`
instances on demand. Property reads block until bound; property writes
bind the variable.

[source,groovy]
----
import groovy.concurrent.Dataflows

def df = new Dataflows()

async { df.z = df.x + df.y }   // blocks on x and y, binds z
async { df.x = 10 }
async { df.y = 5 }

println "Result: ${df.z}"      // 15
----

This is the most concise way to write dataflow programs in Groovy.
Variables are created lazily — no declarations needed.

[source,groovy]
----
def df = new Dataflows()

async { df.fullName = "${df.first} ${df.last}" }
async { df.first = 'John' }
async { df.last = 'Doe' }

assert df.fullName == 'John Doe'
----

=== Accessing the underlying variable

Use `getVariable()` when you need the `DataflowVariable` itself
(e.g., to pass to `Awaitable.all` or check `isBound`):

[source,groovy]
----
def df = new Dataflows()
def v = df.getVariable('x')   // DataflowVariable, does not block
assert !v.isBound()
async { df.x = 42 }
assert await(v) == 42
----

---

### Src Spec Doc Core Concurrent Java (`src/spec/doc/core-concurrent-java.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Groovy Concurrent API for Java (Incubating)

[[concurrent-java-intro]]
== Introduction

The `groovy-concurrent-java` module provides Groovy's concurrent and
parallel API as a standalone Java library — no Groovy runtime required.

Java developers get access to:

- **Structured concurrency** — `AsyncScope`, `Awaitable`
- **Pools** — `Pool`, `ParallelScope`, `ConcurrentConfig`
- **Actors** — `Actor.reactor()`, `Actor.stateful()`
- **Agents** — `Agent` (thread-safe mutable state)
- **Dataflow** — `DataflowVariable`, `AsyncChannel`, `BroadcastChannel`, `ChannelSelect`

This module is published as `org.apache.groovy:groovy-concurrent-java`
and contains a filtered subset of the classes from Groovy core. It must
not be used alongside the full Groovy runtime — Gradle enforces mutual
exclusion via a shared capability, and a runtime warning is logged if
both jars are detected on the classpath.

[[concurrent-java-setup]]
== Setup

=== Gradle

[source,groovy]
----
dependencies {
    implementation 'org.apache.groovy:groovy-concurrent-java:6.0.0'
}
----

=== Maven

[source,xml]
----
<dependency>
    <groupId>org.apache.groovy</groupId>
    <artifactId>groovy-concurrent-java</artifactId>
    <version>6.0.0</version>
</dependency>
----

IMPORTANT: Do not add `groovy-concurrent-java` if you already depend on
`groovy` (the full runtime). The concurrent classes are included in core.

[[concurrent-java-scope]]
== Structured Concurrency

[source,java]
----
import groovy.concurrent.AsyncScope;
import groovy.concurrent.Pool;
import org.apache.groovy.runtime.async.AsyncSupport;

// Basic scope — waits for all children before returning
var result = AsyncScope.withScope(scope -> {
    var a = scope.async(() -> fetchUser(id));
    var b = scope.async(() -> fetchOrders(id));
    return Map.of(
        "user", AsyncSupport.await(a),
        "orders", AsyncSupport.await(b)
    );
});

// With a pool for executor isolation
try (var pool = Pool.cpu()) {
    AsyncScope.withScope(pool, scope -> {
        var task = scope.async(() -> computeResult());
        return AsyncSupport.await(task);
    });
}
----

[[concurrent-java-actors]]
== Actors

[source,java]
----
import groovy.concurrent.Actor;
import org.apache.groovy.runtime.async.AsyncSupport;

// Reactor — stateless, each message produces a reply
var doubler = Actor.<Integer, Integer>reactor(n -> n * 2);
int result = AsyncSupport.await(doubler.sendAndGet(21)); // 42
doubler.stop();

// Stateful — maintains state across messages
var counter = Actor.<String, Integer>stateful(0, (state, msg) -> {
    if ("increment".equals(msg)) return state + 1;
    return state;
});
counter.send("increment");
counter.send("increment");
int count = AsyncSupport.await(counter.sendAndGet("increment")); // 3
counter.stop();
----

[[concurrent-java-agents]]
== Agents

[source,java]
----
import groovy.concurrent.Agent;
import org.apache.groovy.runtime.async.AsyncSupport;

var counter = Agent.create(0);
counter.send(n -> n + 1);
counter.send(n -> n + 1);
counter.send(n -> n + 1);

int result = AsyncSupport.await(counter.getAsync()); // 3
counter.shutdown();
----

[[concurrent-java-dataflow]]
== Dataflow Variables

[source,java]
----
import groovy.concurrent.Awaitable;
import groovy.concurrent.DataflowVariable;
import org.apache.groovy.runtime.async.AsyncSupport;

var x = new DataflowVariable<Integer>();
var y = new DataflowVariable<Integer>();

// z depends on x and y — blocks until both are bound
var z = Awaitable.<Integer>go(() ->
    AsyncSupport.await(x) + AsyncSupport.await(y)
);

// Bind in any order
AsyncSupport.getExecutor().execute(() -> x.bind(10));
AsyncSupport.getExecutor().execute(() -> y.bind(5));

int result = AsyncSupport.await(z); // 15
----

[[concurrent-java-pools]]
== Pools

[source,java]
----
import groovy.concurrent.ParallelScope;
import groovy.concurrent.Pool;
import org.apache.groovy.runtime.async.AsyncSupport;

var result = ParallelScope.withPool(4, scope -> {
    var tasks = new java.util.ArrayList<groovy.concurrent.Awaitable<Integer>>();
    for (int i = 1; i <= 4; i++) {
        int n = i;
        tasks.add(scope.async(() -> n * 10));
    }
    int sum = 0;
    for (var task : tasks) {
        sum += (int) AsyncSupport.await(task);
    }
    return sum;
}); // 100
----

[[concurrent-java-not-included]]
== Features not available in the Java module

The following features require the Groovy runtime and are only
available when using the full `groovy` dependency:

[cols="1,2"]
|===
|Feature |Reason

|`Dataflows` class
|Uses Groovy's `propertyMissing` for dynamic property access

|`async { }` / `await` keywords
|Groovy language syntax, transformed by the Groovy compiler

|`defer { }` / `yield return`
|Groovy language syntax

|`for await (x in channel)`
|Groovy compiler-generated iteration

|`@ActiveObject` / `@ActiveMethod`
|Groovy AST transformation

|Parallel collection methods (`collectParallel`, etc.)
|Registered as Groovy extension methods on `Collection`

|`AsyncClosureUtils` (`wrapAsync`, `wrapAsyncGenerator`)
|Return `Closure` subclasses

|Closure-based APIs (e.g., `scope.async { }`)
|Groovy SAM coercion from Closure to `Supplier`/`Function`
|===

Java users have full access to the underlying APIs using
`java.util.function` types (`Supplier`, `Function`, `Consumer`,
`Predicate`, etc.) and explicit `AsyncSupport.await()` calls
instead of the `await` keyword.

---

### Src Spec Doc Core Differences Java (`src/spec/doc/core-differences-java.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

ifndef::core-semantics[]
:core-semantics: core-semantics.adoc
endif::[]
ifndef::core-syntax[]
:core-syntax: core-syntax.adoc
endif::[]

= Differences with Java

Groovy tries to be as natural as possible for Java developers. We’ve
tried to follow the principle of least surprise when designing Groovy,
particularly for developers learning Groovy who’ve come from a Java
background.

Here we list all the major differences between Java and Groovy.

== Default imports

All these packages and classes are imported by default, i.e. you do not
have to use an explicit `import` statement to use them:

* java.io.*
* java.lang.*
* java.math.BigDecimal
* java.math.BigInteger
* java.net.*
* java.time.*
* java.util.*
* groovy.lang.*
* groovy.util.*

== Multi-methods

In Groovy, the methods which will be invoked are chosen at runtime. This is called runtime dispatch or multi-methods. It
means that the method will be chosen based on the types of the arguments at runtime. In Java, this is the opposite: methods
are chosen at compile time, based on the declared types.

The following code, written as Java code, can be compiled in both Java and Groovy, but it will behave differently:

[source,java]
----
include::../test/DifferencesFromJavaTest.groovy[tags=multimethods,indent=0]
----

In Java, you would have:

[source,java]
----
include::../test/DifferencesFromJavaTest.groovy[tags=multimethods_java,indent=0]
----

Whereas in Groovy:

[source,java]
----
include::../test/DifferencesFromJavaTest.groovy[tags=multimethods_groovy,indent=0]
----

That is because Java will use the static information type, which is that `o` is declared as an `Object`, whereas
Groovy will choose at runtime, when the method is actually called. Since it is called with a `String`, then the
`String` version is called.

== Array initializers

In Java, array initializers take either of these two forms:

[source,java]
----
include::../test/DifferencesFromJavaTest.groovy[tags=arraycreate_fail,indent=0]
----

In Groovy, the `{ ... }` block is reserved for closures.
That means that you cannot create array literals using Java's array initializer shorthand syntax.
You instead borrow Groovy's literal list notation like this:

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=arraycreate_success,indent=0]
----

For Groovy 3+, you can optionally use the Java's array initializer long syntax:

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=arraycreate3_success,indent=0]
----

== Package scope visibility

In Groovy, omitting a modifier on a field doesn't result in a package-private field like in Java:

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=packageprivate_property,indent=0]
----

Instead, it is used to create a _property_, that is to say a _private field_, an associated _getter_ and an associated
_setter_.

It is possible to create a package-private field by annotating it with `@PackageScope`:

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=packageprivate_field,indent=0]
----

== ARM blocks

Java 7 introduced ARM (Automatic Resource Management) blocks (also know as try-with-resources) blocks like this:

[source,java]
----
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }

} catch (IOException e) {
    e.printStackTrace();
}
----

Such blocks are supported from Groovy 3+.
However, Groovy provides various methods relying on closures, which have the same effect while being more idiomatic. For example:

[source,groovy]
----
new File('/path/to/file').eachLine('UTF-8') {
   println it
}
----

or, if you want a version closer to Java:

[source,groovy]
----
new File('/path/to/file').withReader('UTF-8') { reader ->
   reader.eachLine {
       println it
   }
}
----

== Inner classes

WARNING: The implementation of anonymous inner classes and nested classes follow Java closely,
but there are some differences, e.g.
local variables accessed from within such classes don't have to be final.
We piggyback on some implementation details we use for `groovy.lang.Closure`
when generating inner class bytecode.

=== Static inner classes

Here's an example of static inner class:

[source,groovy]
---------------------
include::../test/DifferencesFromJavaTest.groovy[tags=innerclass_1,indent=0]
---------------------

The usage of static inner classes is the best supported one. If you
absolutely need an inner class, you should make it a static one.

=== Anonymous Inner Classes

[source,groovy]
---------------------
include::../test/DifferencesFromJavaTest.groovy[tags=innerclass_2,indent=0]
---------------------

=== Creating Instances of Non-Static Inner Classes

In Java you can do this:

[source,java]
----------------------------------
include::../test/DifferencesFromJavaTest.groovy[tags=innerclass_3_java,indent=0]
----------------------------------

Before 3.0.0, Groovy doesn't support the `y.new X()` syntax. Instead, you have to write `new X(y)`, like in the code below:

[source,groovy]
----------------------------------
include::../test/DifferencesFromJavaTest.groovy[tags=innerclass_3,indent=0]
----------------------------------

[WARNING]
Caution though, Groovy supports calling methods with one
parameter without giving an argument. The parameter will then have the
value null. Basically the same rules apply to calling a constructor.
There is a danger that you will write new X() instead of new X(this) for
example. Since this might also be the regular way we have not yet found
a good way to prevent this problem.

[NOTE]
Groovy 3.0.0 supports Java style syntax for creating instances of non-static inner classes.

== Lambda expressions and the method reference operator

Java 8+ supports lambda expressions and the method reference operator (`::`):

[source,java]
----
Runnable run = () -> System.out.println("Run");  // Java
list.forEach(System.out::println);
----

Groovy 3 and above also support these within the Parrot parser.
In earlier versions of Groovy you should use closures instead:

[source,groovy]
----
Runnable run = { println 'run' }
list.each { println it } // or list.each(this.&println)
----

Since Groovy 6.0, intersection-type casts (https://docs.oracle.com/javase/specs/jls/se21/html/jls-15.html#jls-15.16[JLS §15.16])
are supported on lambdas and method references, so a lambda can opt into `Serializable`
or other marker interfaces, just like in Java:

[source,groovy]
----
Runnable r = (Runnable & Serializable) () -> println('hi') // serializable lambda
----

Groovy additionally accepts the `as` form, where parentheses are required around
the intersection:

[source,groovy]
----
def r = { -> println 'hi' } as (Runnable & Serializable)
----

See the <<{core-semantics}#intersection-cast,Intersection-type cast and coercion>> section in the semantics guide.


== GStrings

As double-quoted string literals are interpreted as `GString` values, Groovy may fail
with compile error or produce subtly different code if a class with `String` literal
containing a dollar character is compiled with Groovy and Java compiler.

While typically, Groovy will auto-cast between `GString` and `String` if an API declares
the type of a parameter, beware of Java APIs that accept an `Object` parameter and then
check the actual type.

== String and Character literals

Singly-quoted literals in Groovy are used for `String`, and double-quoted result in
`String` or `GString`, depending whether there is interpolation in the literal.

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=type_depends_on_quoting_AND_whether_we_actually_interpolate,indent=0]
----

Groovy will automatically cast a single-character `String` to `char` only when assigning to
a variable of type `char`. When calling methods with arguments of type `char` we need
to either cast explicitly or make sure the value has been cast in advance.

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=single_char_strings_are_autocasted,indent=0]
----

Groovy supports two styles of casting and in the case of casting to `char` there
are subtle differences when casting a multi-char strings. The Groovy style cast is
more lenient and will take the first character, while the C-style cast will fail
with exception.

[source,groovy]
----
include::../test/DifferencesFromJavaTest.groovy[tags=chars_c_vs_groovy_cast,indent=0]
----

== Behaviour of `==`

In Java, `==` means equality of primitive types or identity for objects.
In Groovy, `==` means equality in all places.
For non-primitives, it translates to `a.compareTo(b) == 0`,
when evaluating equality for `Comparable` objects,
and `a.equals(b)` otherwise.

To check for identity (reference equality), use the `is` method: `a.is(b)`.
From Groovy 3, you can also use the `===` operator (or negated version): `a === b` (or `c !== d`).

== Primitives and wrappers

In a pure object-oriented language, everything would be an object.
Java takes the stance that primitive types, such as int, boolean and double,
are used very frequently and worthy of special treatment.
Primitives can be efficiently stored and manipulated but can't be used in all contexts where an object could be used.
Luckily, Java auto boxes and unboxes primitives when they are passed as parameters or used as return types:

[source,java]
----
public class Main {           // Java

   float f1 = 1.0f;
   Float f2 = 2.0f;

   float add(Float a1, float a2) { return a1 + a2; }

   Float calc() { return add(f1, f2); } // <1>

    public static void main(String[] args) {
       Float calcResult = new Main().calc();
       System.out.println(calcResult); // => 3.0
    }
}
----
<1> The `add` method expects wrapper then primitive type arguments,
but we are supplying parameters with a primitive then wrapper type.
Similarly, the return type from `add` is primitive, but we need the wrapper type.

Groovy does the same:

[source,groovy]
----
class Main {

    float f1 = 1.0f
    Float f2 = 2.0f

    float add(Float a1, float a2) { a1 + a2 }

    Float calc() { add(f1, f2) }
}

assert new Main().calc() == 3.0
----

Groovy, also supports primitives and object types, however, it goes a little further
in pushing OO purity; it tries hard to treat _everything_ as an object.
Any primitive typed variable or field can be treated like an object, and it
will be link:core-object-orientation.html#_primitive_types[auto-wrapped] as needed.
While primitive types might be used under the covers,
their use should be indistinguishable from normal object use whenever possible,
and they will be boxed/unboxed as needed.

Here is a little example using Java trying to (incorrectly for Java) dereference a primitive `float`:

[source,java]
----
public class Main {           // Java

    public float z1 = 0.0f;

    public static void main(String[] args){
      new Main().z1.equals(1.0f); // DOESN'T COMPILE, error: float cannot be dereferenced
    }
}
----

The same example using Groovy compiles and runs successfully:

[source,groovy]
----
class Main {
    float z1 = 0.0f
}
assert !(new Main().z1.equals(1.0f))
----

Because of Groovy's additional use of un/boxing, it does not follow
Java's behavior of widening taking priority over boxing.
Here's an example using `int`

[source,groovy]
----
include::../test/PrimitiveTest.groovy[tags=widening_vs_boxing,indent=0]
----
<1> This is the method that Java would call, since widening has precedence over unboxing.
<2> This is the method Groovy actually calls, since all primitive references use their wrapper class.

[[primitive-optimisation-numbers]]
=== Numeric Primitive Optimisation with `@CompileStatic`

Since Groovy converts to wrapper classes in more places, you might wonder
whether it produces less efficient bytecode for numeric expressions.
Groovy has a highly optimised set of classes for doing math computations.
When using `@CompileStatic`, expressions involving only primitives
uses the same bytecode that Java would use.

[[zero-edge-case]]
=== Positive/Negative zero edge case

Java float/double operations for both primitives and wrapper classes follow the IEEE 754 standard
but there is an interesting edge case involving positive and negative zero.
The standard supports distinguishing between these two cases and while in many scenarios
programmers may not care about the difference, in some mathematical or data science scenarios
it is important to cater for the distinction.

For primitives, Java maps down onto a special
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.dcmp_op[bytecode instruction]
when comparing such values which has the property that
"Positive zero and negative zero are considered equal".

[source,ruby]
----
jshell> float f1 = 0.0f
f1 ==> 0.0

jshell> float f2 = -0.0f
f2 ==> -0.0

jshell> f1 == f2
$3 ==> true
----

For the wrapper classes, e.g. jdk:java.base/java.lang.Float#equals(java.lang.Object)[Float#equals],
the result is `false` for this same case.

[source,ruby]
----
jshell> Float f1 = 0.0f
f1 ==> 0.0

jshell> Float f2 = -0.0f
f2 ==> -0.0

jshell> f1.equals(f2)
$3 ==> false
----

Groovy on the one hand tries to follow Java behavior closely, but on the other
switches automatically between primitives and wrapped equivalents in more places.
To avoid confusion we recommend the following guidelines:

* If you wish to distinguish between positive and negative zero, use the `equals`
method directly or cast any primitives to their wrapper equivalent before using `==`.
* If you wish to ignore the difference between positive and negative zero, use the `equalsIgnoreZeroSign`
method directly or cast any non-primitives to their primitive equivalent before using `==`.

These guidelines are illustrated in the following example:

[source,groovy]
----
include::../test/PrimitiveTest.groovy[tags=pos_neg_zero,indent=0]
----
<1> Recall that for non-primitives, `==` maps to `.equals()`

== Conversions

Java does automatic widening and narrowing
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html[conversions].

[cols=">2s,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a"]
.Java Conversions
|============================================================================================
|             8+|*Converts to*
| Converts from | *boolean* | *byte* | *short* | *char* | *int* | *long* | *float* | *double*
| boolean       | -         | N      | N       | N      | N     | N      | N       | N
| byte          | N         | -      | Y       | C      | Y     | Y      | Y       | Y
| short         | N         | C      | -       | C      | Y     | Y      | Y       | Y
| char          | N         | C      | C       | -      | Y     | Y      | Y       | Y
| int           | N         | C      | C       | C      | -     | Y      | T       | Y
| long          | N         | C      | C       | C      | C     | -      | T       | T
| float         | N         | C      | C       | C      | C     | C      | -       | Y
| double        | N         | C      | C       | C      | C     | C      | C       | -
|============================================================================================
* 'Y' indicates a conversion Java can make +
* 'C' indicates a conversion Java can make when there is an explicit cast +
* 'T` indicates a conversion Java can make but data is truncated +
* 'N' indicates a conversion Java can't make

Groovy expands greatly on this.

[%autowidth]
[cols=">2s,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a,^1a"]
.Groovy Conversions
|=================================================================================================================================================================================================================
|            18+|*Converts to*
| Converts from |[.rotate]`boolean` |[.rotate]`Boolean` |[.rotate]`byte` |[.rotate]`Byte` |[.rotate]`short` |[.rotate]`Short` |[.rotate]`char` |[.rotate]`Character` |[.rotate]`int` |[.rotate]`Integer` |[.rotate]`long` |[.rotate]`Long` |[.rotate]`BigInteger` |[.rotate]`float` |[.rotate]`Float` |[.rotate]`double` |[.rotate]`Double` |[.rotate]`BigDecimal`
| `boolean`       | -         | B         | N      | N      | N       | N       | N      | N           | N     | N         | N      | N      | N            | N       | N       | N        | N        | N
| `Boolean`       | B         | -         | N      | N      | N       | N       | N      | N           | N     | N         | N      | N      | N            | N       | N       | N        | N        | N
| `byte`          | T         | T         | -      | B      | Y       | Y       | Y      | D           | Y     | Y         | Y      | Y      | Y            | Y       | Y       | Y        | Y        | Y
| `Byte`          | T         | T         | B      | -      | Y       | Y       | Y      | D           | Y     | Y         | Y      | Y      | Y            | Y       | Y       | Y        | Y        | Y
| `short`         | T         | T         | D      | D      | -       | B       | Y      | D           | Y     | Y         | Y      | Y      | Y            | Y       | Y       | Y        | Y        | Y
| `Short`         | T         | T         | D      | T      | B       | -       | Y      | D           | Y     | Y         | Y      | Y      | Y            | Y       | Y       | Y        | Y        | Y
| `char`          | T         | T         | Y      | D      | Y       | D       | -      | D           | Y     | D         | Y      | D      | D            | Y       | D       | Y        | D        | D
| `Character`     | T         | T         | D      | D      | D       | D       | D      | -           | D     | D         | D      | D      | D            | D       | D       | D        | D        | D
| `int`           | T         | T         | D      | D      | D       | D       | Y      | D           | -     | B         | Y      | Y      | Y            | Y       | Y       | Y        | Y        | Y
| `Integer`       | T         | T         | D      | D      | D       | D       | Y      | D           | B     | -         | Y      | Y      | Y            | Y       | Y       | Y        | Y        | Y
| `long`          | T         | T         | D      | D      | D       | D       | Y      | D           | D     | D         | -      | B      | Y            | T       | T       | T        | T        | Y
| `Long`          | T         | T         | D      | D      | D       | T       | Y      | D           | D     | T         | B      | -      | Y            | T       | T       | T        | T        | Y
| `BigInteger`    | T         | T         | D      | D      | D       | D       | D      | D           | D     | D         | D      | D      | -            | D       | D       | D        | D        | T
| `float`         | T         | T         | D      | D      | D       | D       | T      | D           | D     | D         | D      | D      | D            | -       | B       | Y        | Y        | Y
| `Float`         | T         | T         | D      | T      | D       | T       | T      | D           | D     | T         | D      | T      | D            | B       | -       | Y        | Y        | Y
| `double`        | T         | T         | D      | D      | D       | D       | T      | D           | D     | D         | D      | D      | D            | D       | D       | -        | B        | Y
| `Double`        | T         | T         | D      | T      | D       | T       | T      | D           | D     | T         | D      | T      | D            | D       | T       | B        | -        | Y
| `BigDecimal`    | T         | T         | D      | D      | D       | D       | D      | D           | D     | D         | D      | D      | D            | T       | D       | T        | D        | -
|=================================================================================================================================================================================================================
* 'Y' indicates a conversion Groovy can make +
* 'D' indicates a conversion Groovy can make when compiled dynamically or explicitly cast +
* 'T' indicates a conversion Groovy can make but data is truncated +
* 'B' indicates a boxing/unboxing operation +
* 'N' indicates a conversion Groovy can't make.

The truncation uses <<{core-semantics}#the-groovy-truth,Groovy Truth>> when converting to `boolean`/`Boolean`. Converting
from a number to a character casts the `Number.intvalue()` to `char`. Groovy constructs `BigInteger` and `BigDecimal`
using `Number.doubleValue()` when converting from a `Float` or `Double`, otherwise it constructs using `toString()`.
Other conversions have their behavior defined by `java.lang.Number`.

== Extra keywords

Groovy has many of the same keywords as Java and Groovy 3 and above also has the same `var` reserved type as Java.
In addition, Groovy has the following keywords:

* `as`
* `def`
* `in`
* `trait`
* `it` // within closures

Groovy is less stringent than Java in that it allows some keywords to appear in places that would be illegal in Java,
e.g. the following is valid: `var var = [def: 1, as: 2, in: 3, trait: 4]`.
Never-the-less, you are discouraged from using the above keywords in places that might cause confusion even when
the compiler might be happy. In particular, avoid using them for variable, method and class names,
so our previous `var var` example would be considered poor style.

Additional documentation is available for <<{core-syntax}#_keywords,keywords>>.

---

### Src Spec Doc Core Domain Specific Languages (`src/spec/doc/core-domain-specific-languages.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////
ifndef::reldir_root[]
:reldir_root: .
endif::[]
ifndef::core-semantics[]
:core-semantics: core-semantics.adoc
endif::[]
ifndef::xml-userguide[]
:xml-userguide: xml-userguide.adoc
endif::[]
ifndef::jmx[]
:jmx: jmx.adoc
endif::[]

= Domain-Specific Languages

== Command chains

Groovy lets you omit parentheses around the arguments of a
method call for top-level statements. "command chain" feature extends this by allowing us to chain such
parentheses-free method calls, requiring neither parentheses around arguments, nor dots between the chained calls.
The general idea is that a call like `a b c d` will actually be equivalent to `a(b).c(d)`. This
also works with multiple arguments, closure arguments, and even named arguments. Furthermore, such command chains can
also appear on the right-hand side of assignments. Let’s have a look at some examples
supported by this new syntax:

[source,groovy]
---------------------------------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_1,indent=0]

include::../test/CommandChainsTest.groovy[tags=commandchain_2,indent=0]

include::../test/CommandChainsTest.groovy[tags=commandchain_3,indent=0]

include::../test/CommandChainsTest.groovy[tags=commandchain_4,indent=0]

include::../test/CommandChainsTest.groovy[tags=commandchain_5,indent=0]
---------------------------------------------------------------------------------------------------------------

It is also possible to use methods in the chain which take no arguments,
but in that case, the parentheses are needed:

[source,groovy]
-------------------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_6,indent=0]
-------------------------------------------------------------------------------------------------

If your command chain contains an odd number of elements, the chain will
be composed of method / arguments, and will finish by a final property
access:

[source,groovy]
-------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_7,indent=0]
-------------------------------------------------------------------------------------

This command chain approach opens up interesting possibilities in terms of the much wider range of DSLs which
can now be written in Groovy.

The above examples illustrate using a command chain based DSL but not how to create one. There are various strategies
that you can use, but to illustrate creating such a DSL, we will show a couple of examples - first using maps and Closures:

[source,groovy]
------------------------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_impl1,indent=0]
------------------------------------------------------------------------------------------------------

As a second example, consider how you might write a DSL for simplifying
one of your existing APIs. Maybe you need to put this code in front of
customers, business analysts or testers who might be not hard-core Java
developers. We’ll use the `Splitter` from the Google
https://github.com/google/guava[Guava libraries] project as it
already has a nice Fluent API. Here is how we might use it out of the
box:

[source,groovy]
----------------------------------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_impl2,indent=0]
include::../test/CommandChainsTest.groovy[tags=commandchain_impl2_assert,indent=0]
----------------------------------------------------------------------------------------------------------------

It reads fairly well for a Java developer but if that is not your target
audience or you have many such statements to write, it could be
considered a little verbose. Again, there are many options for writing a
DSL. We’ll keep it simple with Maps and Closures. We’ll first write a
helper method:

[source,groovy]
------------------------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_impl3,indent=0]
------------------------------------------------------------------------------------------------------

now instead of this line from our original example:

[source,groovy]
----------------------------------------------------------------------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_impl2_assert,indent=0]
----------------------------------------------------------------------------------------------------------------

we can write this:

[source,groovy]
-----------------------------------------------------
include::../test/CommandChainsTest.groovy[tags=commandchain_impl3_assert,indent=0]
-----------------------------------------------------


== Operator overloading

Various operators in Groovy are mapped onto regular method calls on objects.

This allows you to provide your own Java or Groovy objects which can take advantage of operator overloading. The following table describes the operators supported in Groovy and the methods they map to.

[options="header"]
|======================
|Operator | Method
| `a + b` | a.plus(b)
| `a - b` | a.minus(b)
| `a * b` | a.multiply(b)
| `a ** b` | a.power(b)
| `a / b` | a.div(b)
| `a % b` | a.mod(b)
| `a \| b` | a.or(b)
| `a & b` | a.and(b)
| `a ^ b` | a.xor(b)
| `pass:[a++]` or `pass:[++a]` | a.next()
| `a--` or `--a` | a.previous()
| `a[b]` | a.getAt(b)
| `a[b] = c` | a.putAt(b, c)
| `a << b` | a.leftShift(b)
| `a >> b` | a.rightShift(b)
| `a >>> b` | a.rightShiftUnsigned(b)
| `switch(a) { case(b) : }` | b.isCase(a)
| `if(a)` | a.asBoolean()
| `~a` | a.bitwiseNegate()
| `-a` | a.negative()
| `+a` | a.positive()
| `a as b` | a.asType(b)
| `a == b` | a.equals(b)
| `a != b` | ! a.equals(b)
| `a \<\=> b` | a.compareTo(b)
| `a > b` | a.compareTo(b) > 0
| `a >= b` | a.compareTo(b) >= 0
| `a \< b` | a.compareTo(b) < 0
| `a \<= b` | a.compareTo(b) \<= 0
|======================

== Script base classes
=== The Script class
Groovy scripts are always compiled to classes. For example, a script as simple as:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=simple_script,indent=0]
----

is compiled to a class extending the abstract gapi:groovy.lang.Script[] class. This class contains a single abstract
method called _run_. When a script is compiled, then its body will become the _run_ method, while the other methods
found in the script are found in the implementing class. The `Script` class provides base support for integration
with your application through the `Binding` object, as illustrated in this example:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=integ_binding,indent=0]
----
<1> a binding is used to share data between the script and the calling class
<2> a `GroovyShell` can be used with this binding
<3> input variables are set from the calling class inside the binding
<4> then the script is evaluated
<5> and the `z` variable has been "exported" into the binding

This is a very practical way to share data between the caller and the script, however it may be insufficient or not
practical in some cases. For that purpose, Groovy allows you to set your own base script class. A base script class
has to extend gapi:groovy.lang.Script[] and be a single abstract method type:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=baseclass_def,indent=0]
----

Then the custom script base class can be declared in the compiler configuration, for example:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=use_custom_conf,indent=0]
----
<1> create a custom compiler configuration
<2> set the base script class to our custom base script class
<3> then create a `GroovyShell` using that configuration
<4> the script will then extend the base script class, giving direct access to the `name` property and `greet` method

[[dsl-basescript]]
=== The @BaseScript annotation

As an alternative, it is also possible to use the `@BaseScript` annotation directly into a script:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=use_basescript,indent=0]
----

where `@BaseScript` should annotate a variable which type is the class of the base script. Alternatively, you can set
the base script class as a member of the `@BaseScript` annotation itself:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=use_basescript_alt,indent=0]
----

When using the special no-args `run` method, you can even annotate
that method as shown here:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=jep445_example,indent=0]
----

=== Alternate abstract method

We have seen that the base script class is a single abstract method type that needs to implement the `run` method. The
`run` method is executed by the script engine automatically. In some circumstances it may be interesting to have a base
class which implements the `run` method, but provides an alternative abstract method to be used for the script body.
For example, the base script `run` method might perform some initialization before the `run` method is executed. This
is possible by doing this:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=custom_run_method,indent=0]
----
<1> the base script class should define one (and only one) abstract method
<2> the `run` method can be overridden and perform a task before executing the script body
<3> `run` calls the abstract `scriptBody` method which will delegate to the user script
<4> then it can return something else than the value from the script

If you execute this code:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=custom_run_eval,indent=0]
----

Then you will see that the script is executed, but the result of the evaluation is `1` as returned by the `run`
method of the base class. It is even clearer if you use `parse` instead of `evaluate`, because it would allow you to
execute the `run` method several times on the same script instance:

[source,groovy]
----
include::../test/BaseScriptSpecTest.groovy[tags=custom_run_parse,indent=0]
----

== Adding properties to numbers

In Groovy number types are considered equal to any other types. As such, it is possible to enhance numbers by adding
properties or methods to them. This can be very handy when dealing with measurable quantities for example. Details about
how existing classes can be enhanced in Groovy are found in the link:core-metaprogramming.html#extension-modules[extension
modules] section or the link:core-metaprogramming.html#categories[categories] section.

An illustration of this can be found in Groovy using the `TimeCategory`:

[source,groovy]
----
include::../test/metaprogramming/CategoryTest.groovy[tags=time_category,indent=0]
----
<1> using the `TimeCategory`, a property `minute` is added to the `Integer` class
<2> similarly, the `months` method returns a `groovy.time.DatumDependentDuration` which can be used in calculus

Categories are lexically bound, making them a great fit for internal DSLs.

[[section-delegatesto]]
== @DelegatesTo

[[TheDelegatesToannotation-DSLsmadeeasy]]
=== Explaining delegation strategy at compile time

`@groovy.lang.DelegatesTo` is a documentation and compile-time annotation aimed at:

 * documenting APIs that use closures as arguments
 * providing type information for the static type checker and compiler

The Groovy language is a platform of choice for building DSLs. Using
closures, it’s quite easy to create custom control structures, as well
as it is simple to create builders. Imagine that you have the following
code:

[source,groovy]
---------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=email_builder_usage,indent=0]
---------------------------------------

One way of implementing this is using the builder strategy, which
implies a method, named `email` which accepts a closure as an argument.
The method may delegate subsequent calls to an object that implements
the `from`, `to`, `subject` and `body` methods. Again, `body` is a
method which accepts a closure as an argument and that uses the builder
strategy.

Implementing such a builder is usually done the following way:

[source,groovy]
----------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=email_method_no_delegatesto,indent=0]
----------------------------------------------

the `EmailSpec` class implements the `from`, `to`, … methods. By
calling `rehydrate`, we’re creating a copy of the closure for which we
set the `delegate`, `owner` and `thisObject` values. Setting the owner
and the `this` object is not very important here since we will use the
`DELEGATE_ONLY` strategy which says that the method calls will be
resolved only against the delegate of the closure.

[source,groovy]
----------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=emailspec_no_delegatesto,indent=0]
----------------------------------------------

The `EmailSpec` class has itself a `body` method accepting a closure that is cloned and executed. This is what
we call the builder pattern in Groovy.

One of the problems with the code that we’ve shown is that the user of
the `email` method doesn’t have any information about the methods that
he’s allowed to call inside the closure. The only possible information
is from the method documentation. There are two issues with this: first
of all, documentation is not always written, and if it is, it’s not
always available (javadoc not downloaded, for example). Second, it
doesn’t help IDEs. What would be really interesting, here, is for IDEs
to help the developer by suggesting, once they are in the closure body,
methods that exist on the `email` class.

Moreover, if the user calls a method in the closure which is not defined
by the `EmailSpec` class, the IDE should at least issue a warning (because
it’s very likely that it will break at runtime).

One more problem with the code above is that it is not compatible with static type checking. Type checking would let
the user know if a method call is authorized at compile time instead of runtime, but if you try to perform type
checking on this code:

[source,groovy]
---------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=email_builder_usage,indent=0]
---------------------------------------

Then the type checker will know that there’s an `email` method accepting
a `Closure`, but it will complain about every method call *inside* the
closure, because `from`, for example, is not a method which is defined
in the class. Indeed, it’s defined in the `EmailSpec` class and it has
absolutely no hint to help it knowing that the closure delegate will, at
runtime, be of type `EmailSpec`:

[source,groovy]
---------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=sendmail_typechecked_nodelegatesto,indent=0]
---------------------------------------

will fail compilation with errors like this one:

----
[Static type checking] - Cannot find matching method MyScript#from(java.lang.String). Please check if the declared type is correct and if the method exists.
 @ line 31, column 21.
                       from 'dsl-guru@mycompany.com'
----

[[TheDelegatesToannotation-DelegatesTo]]
=== @DelegatesTo

For those reasons, Groovy 2.1 introduced a new annotation
named `@DelegatesTo`. The goal of this annotation is to solve both the
documentation issue, that will let your IDE know about the expected
methods in the closure body, and it will also solve the type checking
issue, by giving hints to the compiler about what are the potential
receivers of method calls in the closure body.

The idea is to annotate the `Closure` parameter of the `email` method:

[source,groovy]
---------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=email_method_delegatesto,indent=0]
---------------------------------------

What we’ve done here is telling the compiler (or the IDE) that when the
method will be called with a closure, the delegate of this closure will
be set to an object of type `email`. But there is still a problem: the
default delegation strategy is not the one which is used in our method.
So we will give more information and tell the compiler (or the IDE) that
the delegation strategy is also changed:

[source,groovy]
---------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=email_method_delegatesto_strategy,indent=0]
---------------------------------------

Now, both the IDE and the type checker (if you are using `@TypeChecked`)
will be aware of the delegate and the delegation strategy. This is very
nice because it will both allow the IDE to provide smart completion, but
it will also remove errors at compile time that exist only because the
behaviour of the program is normally only known at runtime!

The following code will now pass compilation:

[source,groovy]
---------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=sendmail_typechecked_pass,indent=0]
---------------------------------------

[[TheDelegatesToannotation-DelegatesTomodes]]
=== DelegatesTo modes

`@DelegatesTo` supports multiple modes that we will describe with examples
in this section.

[[TheDelegatesToannotation-Simpledelegation]]
==== Simple delegation

In this mode, the only mandatory parameter is the _value_ which says to
which class we delegate calls. Nothing more. We’re telling the compiler
that the type of the delegate will *always* be of the type documented
by `@DelegatesTo` (note that it can be a subclass, but if it is, the
methods defined by the subclass will not be visible to the type
checker).

[source,groovy]
-----------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=simple_delegation,indent=0]
-----------------------------------------------

[[TheDelegatesToannotation-Delegationstrategy]]
==== Delegation strategy

In this mode, you must specify both the delegate class *and* a
delegation strategy. This must be used if the closure will not be called
with the default delegation strategy, which is `Closure.OWNER_FIRST`.

[source,groovy]
----------------------------------------------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=delegation_with_strategy,indent=0]
----------------------------------------------------------------------------------

[[TheDelegatesToannotation-Delegatetoparameter]]
==== Delegate to parameter

In this variant, we will tell the compiler that we are delegating to
another parameter of the method. Take the following code:

[source,groovy]
-------------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=exec_method_no_delegatesto,indent=0]
-------------------------------------------------

Here, the delegate which will be used is *not* created inside the `exec`
method. In fact, we take an argument of the method and delegate to it.
Usage may look like this:

[source,groovy]
-----------------------
include::../test/DelegatesToSpecTest.groovy[tags=exec_usage,indent=0]
-----------------------

Each of the method calls are delegated to the `email` parameter. This is
a widely used pattern which is also supported by `@DelegatesTo` using a
companion annotation:

[source,groovy]
---------------------------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=exec_method_with_delegatesto,indent=0]
---------------------------------------------------------------

A closure is annotated with `@DelegatesTo`, but this time, without
specifying any class. Instead, we’re annotating another parameter
with `@DelegatesTo.Target`. The type of the delegate is then determined
at compile time. One could think that we are using the parameter type,
which in this case is `Object` but this is not true. Take this code:

[source,groovy]
--------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=delegatesto_flow_typing_header,indent=0]
include::../test/DelegatesToSpecTest.groovy[tags=delegatesto_flow_typing_footer,indent=0]
--------------------------------------

Remember that this works out of the box *without* having to annotate
with `@DelegatesTo`. However, to make the IDE aware of the delegate
type, or the *type checker* aware of it, we need to add `@DelegatesTo`.
And in this case, it will know that the `Greeter` variable is of
type `Greeter`, so it will not report errors on the _sayHello_
method *even if the exec method doesn’t explicitly define the target as
of type Greeter*. This is a very powerful feature, because it prevents
you from writing multiple versions of the same `exec` method for
different receiver types!

In this mode, the `@DelegatesTo` annotation also supports the `strategy`
parameter that we’ve described upper.

[[TheDelegatesToannotation-Multipleclosures]]
==== Multiple closures

In the previous example, the `exec` method accepted only one closure,
but you may have methods that take multiple closures:

[source,groovy]
--------------------------------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_no_delegatesto,indent=0]
--------------------------------------------------------------------

Then nothing prevents you from annotating each closure
with `@DelegatesTo`:

[source,groovy]
--------------------------------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=foobarbaz_classes,indent=0]

include::../test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_header,indent=0]
   ...
include::../test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_footer,indent=0]
--------------------------------------------------------------------

But more importantly, if you have multiple closures *and* multiple
arguments, you can use several targets:

[source,groovy]
-----------------------------------------------------------------------------
include::../test/DelegatesToSpecTest.groovy[tags=foobarbaz_multitarget,indent=0]

include::../test/DelegatesToSpecTest.groovy[tags=multitarget_test,indent=0]
-----------------------------------------------------------------------------

NOTE: At this point, you may wonder why we don’t use the parameter names as
references. The reason is that the information (the parameter name) is
not always available (it’s a debug-only information), so it’s a
limitation of the JVM.

==== Delegating to a generic type

In some situations, it is interesting to instruct the IDE or the compiler that the delegate type will not be a parameter
but a generic type. Imagine a configurator that runs on a list of elements:

[source,groovy]
----
include::../test/DelegatesToSpecTest.groovy[tags=configure_list_method,indent=0]
----

Then this method can be called with any list like this:

[source,groovy]
----
include::../test/DelegatesToSpecTest.groovy[tags=configure_list_usage,indent=0]
----

To let the type checker and the IDE know that the `configure` method calls the closure on each element of the list, you
 need to use `@DelegatesTo` differently:

[source,groovy]
----
include::../test/DelegatesToSpecTest.groovy[tags=configure_list_with_delegatesto,indent=0]
----

`@DelegatesTo` takes an optional `genericTypeIndex` argument that tells what is the index of the generic type that will
be used as the delegate type. This *must* be used in conjunction with `@DelegatesTo.Target` and the index starts at 0. In
the example above, that means that the delegate type is resolved against `List<T>`, and since the generic type at index
0 is `T` and inferred as a `Realm`, the type checker infers that the delegate type will be of type `Realm`.

NOTE: We're using a `genericTypeIndex` instead of a placeholder (`T`) because of JVM limitations.

==== Delegating to an arbitrary type

It is possible that none of the options above can represent the type you want to delegate to. For example, let's define
a mapper class which is parametrized with an object and defines a map method which returns an object of another type:

[source,groovy]
----
include::../test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper,indent=0]
----
<1> The mapper class takes two generic type arguments: the source type and the target type
<2> The source object is stored in a final field
<3> The `map` method asks to convert the source object to a target object

As you can see, the method signature from `map` does not give any information about what object will
be manipulated by the closure. Reading the method body, we know that it will be the `value` which is
of type `T`, but `T` is not found in the method signature, so we are facing a case where none of the
available options for `@DelegatesTo` is suitable. For example, if we try to statically compile this code:

[source,groovy]
----
include::../test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper_test,indent=0]
----

Then the compiler will fail with:

----
Static type checking] - Cannot find matching method TestScript0#length()
----

In that case, you can use the `type` member of the `@DelegatesTo` annotation to reference `T` as a type token:

[source,groovy]
----
include::../test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper_fixed,indent=0]
----
<1> The `@DelegatesTo` annotation references a generic type which is not found in the method signature

Note that you are not limited to generic type tokens. The `type` member can be used to represent complex types, such
as `List<T>` or `Map<T,List<U>>`. The reason why you should use that in last resort is that the type is only checked
when the type checker finds usage of `@DelegatesTo`, not when the annotated method itself is compiled. This means that
type safety is only ensured at the call site. Additionally, compilation will be slower (though probably unnoticeable for
most cases).

[[compilation-customizers]]
== Compilation customizers
=== Introduction

Whether you are using `groovyc` to compile classes or a `GroovyShell`,
for example, to execute scripts, under the hood, a _compiler configuration_ is used. This configuration holds information
like the source encoding or the classpath but it can also be used to perform more operations like adding imports by
default, applying AST transformations transparently or disabling global AST transformations.

The goal of compilation customizers is to make those common tasks easy to implement. For that, the `CompilerConfiguration`
class is the entry point. The general schema will always be based on the following code:

[source,groovy]
--------------------------------------------------------
import org.codehaus.groovy.control.CompilerConfiguration
// create a configuration
def config = new CompilerConfiguration()
// tweak the configuration
config.addCompilationCustomizers(...)
// run your script
def shell = new GroovyShell(config)
shell.evaluate(script)
--------------------------------------------------------

Compilation customizers must extend the _org.codehaus.groovy.control.customizers.CompilationCustomizer_ class. A customizer works:

* on a specific compilation phase
* on _every_ class node being compiled

You can implement your own compilation customizer but Groovy includes some of the most common operations.

=== Import customizer

Using this compilation customizer, your code will have imports added
transparently. This is in particular useful for scripts implementing a
DSL where you want to avoid users from having to write imports. The
import customizer will let you add all the variants of imports the
Groovy language allows, that is:

* class imports, optionally aliased
* star imports
* static imports, optionally aliased
* static star imports

[source,groovy]
-----------------------------------------------------------------------------------------------------
import org.codehaus.groovy.control.customizers.ImportCustomizer

include::../test/CustomizersTest.groovy[tags=import_cz,indent=0]
-----------------------------------------------------------------------------------------------------

A detailed description of all shortcuts can be found in gapi:org.codehaus.groovy.control.customizers.ImportCustomizer[]

=== AST transformation customizer

The AST transformation customizer is meant to apply AST transformations
transparently. Unlike global AST transformations that apply on every
class being compiled as long as the transform is found on classpath
(which has drawbacks like increasing the compilation time or side
effects due to transformations applied where they should not), the
customizer will allow you to selectively apply a transform only for
specific scripts or classes.

As an example, let’s say you want to be able to use `@Log` in a script.
The problem is that `@Log` is normally applied on a class node and a
script, by definition, doesn’t require one. But implementation wise,
scripts are classes, it’s just that you cannot annotate this implicit
class node with `@Log`. Using the AST customizer, you have a workaround
to do it:

[source,groovy]
--------------------------------------------------------------------------
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer
import groovy.util.logging.Log

include::../test/CustomizersTest.groovy[tags=ast_cz_simple,indent=0]
--------------------------------------------------------------------------

That’s all! Internally, the `@Log` AST transformation is applied to
every class node in the compilation unit. This means that it will be
applied to the script, but also to classes defined within the script.

If the AST transformation that you are using accepts parameters, you can
use parameters in the constructor too:

[source,groovy]
-----------------------------------------------------------------------------------------------------------------
include::../test/CustomizersTest.groovy[tags=ast_cz_customname,indent=0]
-----------------------------------------------------------------------------------------------------------------

As the AST transformation customizers works with objects instead of AST
nodes, not all values can be converted to AST transformation parameters.
For example, primitive types are converted to `ConstantExpression` (that
is `LOGGER` is converted to `new ConstantExpression('LOGGER')`, but if
your AST transformation takes a closure as an argument, then you have to
give it a `ClosureExpression`, like in the following example:

[source,groovy]
--------------------------------------------------------------------------------------------------------------
include::../../../subprojects/groovy-astbuilder/src/spec/test/CustomizersTest.groovy[tags=ast_cz_closure,indent=0]
--------------------------------------------------------------------------------------------------------------

For a complete list of options, please refer to gapi:org.codehaus.groovy.control.customizers.ASTTransformationCustomizer[]

=== Secure AST customizer

CAUTION: Despite its name, this customizer is *not* a sandbox and *not* a security
boundary. It secures the *grammar* not the *execution* - it is a best-effort restriction of the grammar available to a DSL, and nothing
more. It cannot constrain what otherwise-permitted code does at runtime, its coverage of
the source is deliberately partial (see <<secure-ast-limitations,Limitations>> below), and
an author of the source being compiled can work around it. The Apache Groovy
https://github.com/apache/groovy/blob/master/THREAT_MODEL.md[threat model] treats it as a
hardening aid rather than a security boundary: a demonstrated bypass is expected
behaviour, not a vulnerability. If you must run partially-trusted scripts, layer real
isolation *outside* the language — a separate process or JVM, an OS or container sandbox,
least-privilege credentials, and network egress controls — and treat this customizer as
one layer within that, never the perimeter.

This customizer will allow the developer of a DSL to restrict the
*grammar* of the language, for example, to prevent users from using particular constructs.
It is only ``secure'' in that one aspect, i.e. limiting the allowable constructs within a DSL.
It does *not* replace other aspects of security which might additionally
be needed.
The only reason for it to exist is to limit the expressiveness of the
language. This customizer only works at the AST (abstract syntax tree)
level, not at runtime! It can be strange at first glance, but it makes
much more sense if you think of Groovy as a platform to build DSLs. You
may not want a user to have a complete language at hand. In the example
below, we will demonstrate it using an example of language that only
allows arithmetic operations, but this customizer allows you to:

* allow/disallow creation of closures
* allow/disallow imports
* allow/disallow package definition
* allow/disallow definition of methods
* restrict the receivers of method calls
* restrict the kind of AST expressions a user can use
* restrict the tokens (grammar-wise) a user can use
* restrict the types of the constants that can be used in code

For all those features, the secure AST customizer works using either an
allowed list (list of elements that are permitted) *or* a disallowed list (list of
elements that are not permitted). For each type of feature (imports,
tokens, …) you have the choice to use either an allowed or disallowed list,
but you can mix dis/allowed lists for distinct features. Typically,
you will choose allowed lists (which permits only the constructs listed and disallows all others).

[source,groovy]
-------------------------------------------------------------------------------------
import org.codehaus.groovy.control.customizers.SecureASTCustomizer
import static org.codehaus.groovy.syntax.Types.* <1>

include::../test/CustomizersTest.groovy[tags=secure_cz,indent=0]
-------------------------------------------------------------------------------------
<1> use for token types from gapi:org.codehaus.groovy.syntax.Types[]
<2> you can use class literals here

If what the secure AST customizer provides out of the box isn’t enough
for your needs, before creating your own compilation customizer, you
might be interested in the expression and statement checkers that the
AST customizer supports. Basically, it allows you to add custom checks
on the AST tree, on expressions (expression checkers) or statements
(statement checkers). For this, you must
implement `org.codehaus.groovy.control.customizers.SecureASTCustomizer.StatementChecker`
or `org.codehaus.groovy.control.customizers.SecureASTCustomizer.ExpressionChecker`.

Those interfaces define a single method called `isAuthorized`, returning
a boolean, and taking a `Statement` (or `Expression`) as a parameter. It
allows you to perform complex logic over expressions or statements to
tell if a user is allowed to do it or not.

For example, there's no predefined configuration flag in the customizer which
will let you prevent people from using an attribute expression. Using a custom
checker, it is trivial:

[source,groovy]
----------------------------------------------------------------------
include::../test/CustomizersTest.groovy[tags=secure_cz_custom,indent=0]
----------------------------------------------------------------------

Then we can make sure that this works by evaluating a simple script:

[source,groovy]
----
new GroovyShell(config).evaluate '''
include::../test/CustomizersTest.groovy[tags=secure_cz_custom_assert,indent=4]
'''
----
<1> will fail compilation

Statements can be checked using gapi:org.codehaus.groovy.control.customizers.SecureASTCustomizer.StatementChecker[]
Expressions can be checked using gapi:org.codehaus.groovy.control.customizers.SecureASTCustomizer.ExpressionChecker[]

[[secure-ast-limitations]]
==== Limitations of the secure AST customizer

Coverage is partial by design, so it is worth knowing where the checks do and do not
reach. The customizer visits the script statement block, method and constructor bodies,
static and instance initializer blocks, and field initializer expressions. It does *not*
visit the following, so restrictions such as `disallowedReceivers`, the statement and
expression allow/disallow lists, and your own custom checkers do not apply to code
appearing there:

* annotation members, including closure arguments to annotations
* code carrying no source position, which is how constructors, initializers and fields
  added by the compiler or by an AST transformation are told apart from those written by
  the author of the source being secured — a script class always has generated
  constructors, for example, and checking those would reject valid programs

A generated member may still *contain* code you wrote, because a transformation can move it
there: `@TupleConstructor(pre=...)` and `@MapConstructor(pre=...)` relocate the supplied
closure body into the constructor they generate, and `@ConditionalInterrupt` relocates its
condition into a synthetic method. Such code keeps its original source position and is
checked wherever it was moved to.

Note that a constructor is not a ``method definition'' as far as `methodDefinitionAllowed`
is concerned: its body is checked, but declaring one remains permitted.

Import restrictions apply to actual `import` statements, so they have no effect on a
fully-qualified reference such as `new java.lang.ProcessBuilder(...)`. The
`indirectImportCheckEnabled` flag exists to catch some of those, but only within the code
the customizer visits.

More fundamentally, *compiling* Groovy source is itself code execution, whether or not you
subsequently run the result: global AST transforms found on the compile classpath,
`@groovy.transform.ASTTest`, `@Grab` dependency resolution and static initializers all run
during compilation, before and independently of any customizer you configure. Restricting
the grammar of source that you nevertheless compile does not change this. When compiling
source you do not fully trust, you should also set the `groovy.grape.enable` system
property to `false`, keep the compile classpath under your control, and apply the
out-of-language isolation described above.

=== Source aware customizer

This customizer may be used as a filter on other customizers. The
filter, in that case, is the `org.codehaus.groovy.control.SourceUnit`.
For this, the source aware customizer takes another customizer as a
delegate, and it will apply customization of that delegate only and only
if predicates on the source unit match.

`SourceUnit` gives you access to multiple things but in particular the
file being compiled (if compiling from a file, of course). It gives
you the potential to perform operation based on the file name, for
example. Here is how you would create a source aware customizer:

[source,groovy]
--------------------------------------------------------------------
import org.codehaus.groovy.control.customizers.SourceAwareCustomizer
import org.codehaus.groovy.control.customizers.ImportCustomizer

include::../test/CustomizersTest.groovy[tags=source_cz,indent=0]
--------------------------------------------------------------------

Then you can use predicates on the source aware customizer:

[source,groovy]
--------------------------------------------------------------------------
include::../test/CustomizersTest.groovy[tags=source_cz_predicates,indent=0]
--------------------------------------------------------------------------

=== Customizer builder

If you are using compilation customizers in Groovy code (like the
examples above) then you can use an alternative syntax to customize compilation.
A builder (`org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder`)
simplifies the creation of customizers using a hierarchical DSL.

[source,groovy]
-----------------------------------------------------------------------------------------------------
import org.codehaus.groovy.control.CompilerConfiguration
import static org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder.withConfig <1>

include::../test/CustomizersTest.groovy[tags=customizer_withconfig,indent=0]
-----------------------------------------------------------------------------------------------------
<1> static import of the builder method
<2> configuration goes here

The code sample above shows how to use the builder. A static
method, _withConfig_, takes a closure corresponding to the builder code,
and automatically registers compilation customizers to the
configuration. Every compilation customizer available in the distribution
can be configured this way:

==== Import customizer

[source,groovy]
----------------------------------------------------------------------------------
withConfig(configuration) {
   imports { // imports customizer
      normal 'my.package.MyClass' // a normal import
      alias 'AI', 'java.util.concurrent.atomic.AtomicInteger' // an aliased import
      star 'java.util.concurrent' // star imports
      staticMember 'java.lang.Math', 'PI' // static import
      staticMember 'pi', 'java.lang.Math', 'PI' // aliased static import
   }
}
----------------------------------------------------------------------------------

==== AST transformation customizer

[source,groovy]
-------------------------------------------
withConfig(conf) {
   ast(Log) <1>
}

withConfig(conf) {
   ast(Log, value: 'LOGGER') <2>
}
-------------------------------------------
<1> apply @Log transparently
<2> apply @Log with a different name for the logger

==== Secure AST customizer

[source,groovy]
--------------------------------------
withConfig(conf) {
   secureAst {
       closuresAllowed = false
       methodDefinitionAllowed = false
   }
}
--------------------------------------

==== Source aware customizer

[source,groovy]
--------------------------------------------------------------------------------------
withConfig(configuration){
    source(extension: 'sgroovy') {
        ast(CompileStatic) <1>
    }
}

withConfig(configuration){
    source(extensions: ['sgroovy','sg']) {
        ast(CompileStatic) <2>
    }
}

withConfig(configuration) {
    source(extensionValidator: { it.name in ['sgroovy','sg']}) {
        ast(CompileStatic) <2>
    }
}

withConfig(configuration) {
    source(basename: 'foo') {
        ast(CompileStatic) <3>
    }
}

withConfig(configuration) {
    source(basenames: ['foo', 'bar']) {
        ast(CompileStatic) <4>
    }
}

withConfig(configuration) {
    source(basenameValidator: { it in ['foo', 'bar'] }) {
        ast(CompileStatic) <4>
    }
}

withConfig(configuration) {
    source(unitValidator: { unit -> !unit.AST.classes.any { it.name == 'Baz' } }) {
        ast(CompileStatic) <5>
    }
}
--------------------------------------------------------------------------------------
<1> apply CompileStatic AST annotation on .sgroovy files
<2> apply CompileStatic AST annotation on .sgroovy or .sg files
<3> apply CompileStatic AST annotation on files whose name is 'foo'
<4> apply CompileStatic AST annotation on files whose name is 'foo' or 'bar'
<5> apply CompileStatic AST annotation on files that do not contain a class named 'Baz'

==== Inlining a customizer

Inlined customizer allows you to write a compilation customizer
directly, without having to create a class for it.

[source,groovy]
--------------------------------------------------------------
withConfig(configuration) {
    inline(phase:'CONVERSION') { source, context, classNode ->  <1>
        println "visiting $classNode"                           <2>
    }
}
--------------------------------------------------------------
<1> define an inlined customizer which will execute at the CONVERSION phase
<2> prints the name of the class node being compiled

==== Multiple customizers

Of course, the builder allows you to define multiple customizers at
once:

[source,groovy]
---------------------------
withConfig(configuration) {
   ast(ToString)
   ast(EqualsAndHashCode)
}
---------------------------

=== The `configscript` commandline parameter

So far, we have described how you can customize compilation using
a `CompilationConfiguration` class, but this is only possible if you
embed Groovy and that you create your own instances
of `CompilerConfiguration` (then use it to create a
`GroovyShell`, `GroovyScriptEngine`, …).

If you want it to be applied on the classes you compile with the normal
Groovy compiler (that is to say with `groovyc`, `ant` or `gradle`,
for example), it is possible to use a commandline parameter named `configscript`
that takes a Groovy configuration script as argument.

This script gives you access to the `CompilerConfiguration` instance *before*
the files are compiled (exposed into the configuration script as a variable named `configuration`),
so that you can tweak it.

It also transparently integrates the compiler configuration builder above. As an example, let's see
how you would activate static compilation by default on all classes.

==== Configscript example: Static compilation by default

Normally, classes in Groovy are compiled with a dynamic runtime. You can activate static compilation
by placing an annotation named `@CompileStatic` on any class. Some people would like to have this
mode activated by default, that is to say not having to annotate (potentially many) classes.
Using `configscript`,  makes this possible.
First of all, you need to create a file named `config.groovy` into say `src/conf` with
the following contents:

[source,groovy]
--------------------------------------
withConfig(configuration) { <1>
   ast(groovy.transform.CompileStatic)
}
--------------------------------------
<1> _configuration_ references a `CompilerConfiguration` instance

That is actually all you need. You don’t have to import the builder, it’s automatically
exposed in the script. Then, compile your files using the following command line:

---------------------------------------------------------------------------
groovyc -configscript src/conf/config.groovy src/main/groovy/MyClass.groovy
---------------------------------------------------------------------------

We strongly recommend you to separate configuration files from classes,
hence why we suggest using the `src/main` and `src/conf` directories above.

==== Configscript example: Setting system properties

In a configuration script you can also set system properties, e.g.:

[source,groovy]
--------------------------------------
System.setProperty('spock.iKnowWhatImDoing.disableGroovyVersionCheck', 'true')
--------------------------------------

If you have numerous system properties to set, then using a configuration file
will reduce the need to set a bunch of system properties with a long command line
or appropriately defined environment variable.
You can also share all the settings by simply sharing the config file.

=== AST transformations

If:

* runtime metaprogramming doesn't allow you to do what you want
* you need to improve the performance of the execution of your DSLs
* you want to leverage the same syntax as Groovy but with different semantics
* you want to improve support for type checking in your DSLs

Then AST transformations are the way to go. Unlike the techniques used so far, AST transformations are meant to
change or generate code before it is compiled to bytecode. AST transformations are capable of adding new methods at
compile time for example, or totally changing the body of a method based on your needs. They are a very powerful tool
but also come at the price of not being easy to write. For more information about AST transformations, please take
a look at the https://docs.groovy-lang.org/latest/html/documentation/index.html#_compile_time_metaprogramming[compile-time
metaprogramming] section of this manual.

== Custom type checking extensions

It may be interesting, in some circumstances, to provide feedback about wrong code to the user as soon as possible,
that is to say when the DSL script is compiled, rather than having to wait for the execution of the script. However,
this is not often possible with dynamic code. Groovy actually provides a practical answer to this known as
link:core-semantics.html#type-checking-extensions[type checking extensions].

== Builders

Many tasks require building things and the builder pattern is one technique
used by developers to make building things easier, especially building
of structures which are hierarchical in nature.
This pattern is so ubiquitous that Groovy has special built-in support.
Firstly, there are many built-in builders. Secondly, there are
classes which make it easier to write your own builders.

=== Existing builders

Groovy comes with many built-in builders. Let's look at some of them.

==== MarkupBuilder

See <<{xml-userguide}#_markupbuilder,Creating Xml - MarkupBuilder>>.

==== StreamingMarkupBuilder

See <<{xml-userguide}#_streamingmarkupbuilder,Creating Xml - StreamingMarkupBuilder>>.

include::../../../subprojects/groovy-xml/src/spec/doc/_sax-builder.adoc[leveloffset=+3]

include::../../../subprojects/groovy-xml/src/spec/doc/_stax-builder.adoc[leveloffset=+3]

include::../../../subprojects/groovy-xml/src/spec/doc/_dom-builder.adoc[leveloffset=+3]

==== NodeBuilder

`NodeBuilder` is used for creating nested trees of gapi:groovy.util.Node[Node] objects for handling arbitrary data.
To create a simple user list you use a `NodeBuilder` like this:

[source,groovy]
----
include::../test/builder/NodeBuilderTest.groovy[tags=node_builder_example,indent=0]
----

Now you can process the data further, e.g. by using <<{core-semantics}#gpath_expressions,GPath expressions>>:

[source,groovy]
----
include::../test/builder/NodeBuilderTest.groovy[tags=node_builder_gpath_assert,indent=0]
----

include::../../../subprojects/groovy-json/src/spec/doc/_json-builder.adoc[leveloffset=+3]

include::../../../subprojects/groovy-json/src/spec/doc/_streaming-jason-builder.adoc[leveloffset=+3]

include::../../../subprojects/groovy-swing/src/spec/doc/_swing-builder.adoc[leveloffset=+3]

include::../../../subprojects/groovy-ant/src/spec/doc/_ant-builder.adoc[leveloffset=+3]

==== CliBuilder

`CliBuilder` provides a compact way to specify the available options for a commandline application and then
automatically parse the application's commandline parameters according to that specification. By convention,
a distinction is made between _option_ commandline parameters and any remaining parameters which are passed
to an application as its arguments. Typically, several types of options might be supported such as `-V` or
`--tabsize=4`. `CliBuilder` removes the burden of developing lots of code for commandline processing.
Instead, it supports a somewhat declarative approach to declaring your options and then provides a single call
to parse the commandline parameters with a simple mechanism to interrogate the options (you can think of this
as a simple model for your options).

Even though the details of each commandline you create could be quite different, the same main steps are
followed each time. First, a `CliBuilder` instance is created. Then, allowed commandline options are defined.
This can be done using a _dynamic api_ style or an _annotation_ style.
The commandline parameters are then parsed according to the options specification resulting in a
collection of options which are then interrogated.

Here is a simple example `Greeter.groovy` script illustrating usage:

[source,groovy]
---------------------------
// import of CliBuilder not shown                          <1>
// specify parameters
def cli = new CliBuilder(usage: 'groovy Greeter [option]') <2>
cli.a(longOpt: 'audience', args: 1, 'greeting audience')   <3>
cli.h(longOpt: 'help', 'display usage')                    <4>

// parse and process parameters
def options = cli.parse(args)                              <5>
if (options.h) cli.usage()                                 <6>
else println "Hello ${options.a ? options.a : 'World'}"    <7>
---------------------------
<1> Earlier versions of Groovy had a CliBuilder in the `groovy.util` package and no import was necessary.
In Groovy 2.5, this approach became deprecated: applications should instead choose the `groovy.cli.picocli` or `groovy.cli.commons` version.
The groovy.util version in Groovy 2.5 points to the commons-cli version for backwards compatibility but has been removed in Groovy 3.0.
<2> define a new `CliBuilder` instance specifying an optional usage string
<3> specify a `-a` option taking a single argument with an optional long variant `--audience`
<4> specify a `-h` option taking no arguments with an optional long variant `--help`
<5> parse the commandline parameters supplied to the script
<6> if the `h` option is found display a usage message
<7> display a standard greeting or, if the `a` option is found, a customized greeting

Running this script with no commandline parameters, i.e.:

[source,shell]
----
> groovy Greeter
----

results in the following output:

----
Hello World
----

Running this script with `-h` as the single commandline parameter, i.e.:

[source,shell]
----
> groovy Greeter -h
----

results in the following output:

----
usage: groovy Greeter [option]
 -a,--audience <arg>   greeting audience
 -h,--help             display usage
----

Running this script with `--audience Groovologist` as the commandline parameters, i.e.:

[source,shell]
----
> groovy Greeter --audience Groovologist
----

results in the following output:

----
Hello Groovologist
----

When creating the `CliBuilder` instance in the above example, we set the optional `usage` property
within the constructor call. This follows Groovy's normal ability to set additional properties
of the instance during construction. There are numerous other properties which can be set
such as `header` and `footer`. For the complete set of available properties, see the
available properties for the gapi:groovy.util.CliBuilder[CliBuilder] class.

When defining an allowed commandline option, both a short name (e.g. "h" for the `help` option shown previously)
and a short description (e.g. "display usage" for the `help` option) must be supplied.
In our example above, we also set some
additional properties such as `longOpt` and `args`. The following additional
properties are supported when specifying an allowed commandline option:

[options="header"]
|======================
| Name           | Description | Type
| argName        | the name of the argument for this option used in output | `String`
| longOpt        | the long representation or long name of the option | `String`
| args           | the number of argument values | `int` or `String` {nbsp} {nbsp} (1)
| optionalArg    | whether the argument value is optional | `boolean`
| required       | whether the option is mandatory | `boolean`
| type           | the type of this option | `Class`
| valueSeparator | the character that is the value separator | `char` {nbsp} {nbsp} (2)
| defaultValue   | a default value | `String`
| convert        | converts the incoming String to the required type | `Closure` {nbsp} {nbsp} (1)
|======================
(1) More details later +
(2) Single character Strings are coerced to chars in special cases in Groovy

If you have an option with only a `longOpt` variant, you can use the special shortname of 'pass:[_]'
to specify the option, e.g. : `cli.pass:[_](longOpt: 'verbose', 'enable verbose logging')`.
Some of the remaining named parameters should be fairly self-explanatory while others deserve
a bit more explanation. But before further explanations, let's look at ways of using
`CliBuilder` with annotations.

===== Using Annotations and an interface

Rather than making a series of method calls (albeit in a very declarative mini-DSL form)
to specify the allowable options, you can provide an interface specification of the allowable options where
annotations are used to indicate and provide details for those options and for how unprocessed
parameters are handled. Two annotations are used: gapi:groovy.cli.Option[] and gapi:groovy.cli.Unparsed[].

Here is how such a specification can be defined:

[source,groovy]
----
include::../../testFixtures/groovy/cli/GreeterI.groovy[tags=annotationInterfaceSpec,indent=0]
----
<1> Specify a Boolean option set using `-h` or `--help`
<2> Specify a String option set using `-a` or `--audience`
<3> Specify where any remaining parameters will be stored

Note how the long name is automatically determined from the interface method name.
You can use the `longName` annotation attribute to override that behavior and specify
a custom long name if you wish or use a longName of 'pass:[_]' to indicate that no long name
is to be provided. You will need to specify a shortName in such a case.

Here is how you could use the interface specification:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=annotationInterface,indent=0]
----
<1> Create a `CliBuilder` instance as before with optional properties
<2> Parse parameters using the interface specification
<3> Interrogate options using the methods from the interface
<4> Parse a different set of parameters
<5> Interrogate the remaining parameters

When `parseFromSpec` is called, `CliBuilder` automatically creates an instance implementing the interface
and populates it. You simply call the interface methods to interrogate the option values.

===== Using Annotations and an instance

Alternatively, perhaps you already have a domain class containing the option information.
You can simply annotate properties or setters from that class to enable `CliBuilder` to appropriately
populate your domain object. Each annotation both describes that option's properties through the annotation
attributes and indicates the setter the `CliBuilder` will use to populate that option in your domain object.

Here is how such a specification can be defined:

[source,groovy]
----
include::../../testFixtures/groovy/cli/GreeterC.groovy[tags=annotationClassSpec,indent=0]
----
<1> Indicate that a Boolean property is an option
<2> Indicate that a String property (with explicit setter) is an option
<3> Specify where any remaining args will be stored

And here is how you could use the specification:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=annotationClass,indent=0]
----
<1> Create a `CliBuilder` instance as before with optional parameters
<2> Create an instance for `CliBuilder` to populate
<3> Parse arguments populating the supplied instance
<4> Interrogate the String option property
<5> Interrogate the remaining arguments property

When `parseFromInstance` is called, `CliBuilder` automatically populates your instance.
You simply interrogate the instance properties (or whatever accessor methods you have provided
in your domain object) to access the option values.

===== Using Annotations and a script

Finally, there are two additional convenience annotation aliases specifically for scripts. They
simply combine the previously mentioned annotations and gapi:groovy.transform.Field[].
The groovydoc for those annotations reveals the details: gapi:groovy.cli.OptionField[] and
gapi:groovy.cli.UnparsedField[].

Here is an example using those annotations in a self-contained script that would be called
with the same arguments as shown for the instance example earlier:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=annotationScript,indent=0]
----

===== Options with arguments

We saw in our initial example that some options act like flags, e.g. `Greeter -h` but
others take an argument, e.g. `Greeter --audience Groovologist`. The simplest cases
involve options which act like flags or have a single (potentially optional) argument.
Here is an example involving those cases:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withArgument,indent=0]
----
<1> An option that is simply a flag - the default; setting args to 0 is allowed but not needed.
<2> An option with exactly one argument
<3> An option with an optional argument; it acts like a flag if the option is left out
<4> An example using this spec where an argument is supplied to the 'c' option
<5> An example using this spec where no argument is supplied to the 'c' option; it's just a flag

Note: when an option with an optional argument is encountered, it will (somewhat) greedily consume the
next parameter from the supplied commandline parameters. If however, the next parameter matches a known long or short
option (with leading single or double hyphens), that will take precedence, e.g. `-b` in the above example.

Option arguments may also be specified using the annotation style. Here is an interface option specification
illustrating such a definition:

[source,groovy]
----
include::../../testFixtures/groovy/cli/WithArgsI.groovy[tags=withArgumentInterfaceSpec,indent=0]
----

And here is how it is used:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withArgumentInterface,indent=0]
----

This example makes use of an array-typed option specification. We cover this in more detail shortly when we discuss
multiple arguments.

===== Specifying a type

Arguments on the commandline are by nature Strings (or arguably can be considered Booleans for flags) but can be
converted to richer types automatically by supplying additional typing information. For the
annotation-based argument definition style, these types are supplied using the field types for annotation
properties or return types of annotated methods (or the setter argument type for setter methods).
For the dynamic method style of argument definition a special 'type' property is supported
which allows you to specify a Class name.

When an explicit type is defined, the `args` named-parameter is assumed to be 1 (except for Boolean-typed
options where it is 0 by default). An explicit `args` parameter can still be provided if needed.
Here is an example using types with the dynamic api argument definition style:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withType,indent=0]
----

Primitives, numeric types, files, enums and arrays thereof, are supported (they are converted using
gapi:org.codehaus.groovy.runtime.StringGroovyMethods#asType[StringGroovyMethods#asType(String, Class)]).

===== Custom parsing of the argument String

If the supported types aren't sufficient, you can supply a closure to handle the String to rich type conversion
for you. Here is a sample using the dynamic api style:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withConvert,indent=0]
----

Alternatively, you can use the annotation style by supplying the conversion closure as an annotation parameter.
Here is an example specification:

[source,groovy]
----
include::../../testFixtures/groovy/cli/WithConvertI.groovy[tags=withConvertInterfaceSpec,indent=0]
----

And an example using that specification:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withConvertInterface,indent=0]
----

===== Options with multiple arguments

Multiple arguments are also supported using an `args` value greater than 1. There is a special named parameter,
`valueSeparator`, which can also be optionally used when processing multiple arguments. It allows some additional
flexibility in the syntax supported when supplying such argument lists on the commandline. For example,
supplying a value separator of ',' allows a comma-delimited list of values to be passed on the commandline.

The `args` value is normally an integer. It can be optionally supplied as a String. There are two special
String symbols: `+` and `\*`.
The `*` value means 0 or more. The `+` value means 1 or more.
The `*` value is the same as using `+` and also setting the `optionalArg` value to true.

Accessing the multiple arguments follows a special convention. Simply add an 's' to the normal property
you would use to access the argument option and you will retrieve all the supplied arguments as a list.
So, for a short option named 'a', you access the first 'a' argument using `options.a` and the list of
all arguments using `options.as`. It's fine to have a shortname or longname ending in 's' so long as you
don't also have the singular variant without the 's'. So, if `name` is one of your options with multiple arguments
and `guess` is another with a single argument, there will be no confusion using `options.names` and `options.guess`.

Here is an excerpt highlighting the use of multiple arguments:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=multipleArgs,indent=0]
----
<1> Args value supplied as a String and comma value separator specified
<2> One or more arguments are allowed
<3> Two commandline parameters will be supplied as the 'b' option's list of arguments
<4> Access the 'a' option's first argument
<5> Access the 'a' option's list of arguments
<6> An alternative syntax for specifying two arguments for the 'a' option
<7> The arguments to the 'b' option supplied as a comma-separated value

As an alternative to accessing multiple arguments using the _plural name_ approach, you can use an
array-based type for the option. In this case, all options will always be returned via the array
which is accessed via the normal singular name. We'll see an example of this next when discussing
types.

Multiple arguments are also supported using the annotation style of option definition by using an
array type for the annotated class member (method or property) as this example shows:

[source,groovy]
----
include::../../testFixtures/groovy/cli/ValSepI.groovy[tags=multipleArgsInterfaceSpec,indent=0]
----

And used as follows:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=multipleArgsInterface,indent=0]
----

===== Types and multiple arguments

Here is an example using types and multiple arguments with the dynamic api argument definition style:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withTypeMultiple,indent=0]
----
<1> For an array type, the trailing 's' can be used but isn't needed

===== Setting a default value

Groovy makes it easy using the Elvis operator to provide a default value at the point of usage of some variable,
e.g. `String x = someVariable ?: 'some default'`. But sometimes you wish to make such a default part of the
options specification to minimise the interrogators work in later stages. `CliBuilder` supports the `defaultValue`
property to cater for this scenario.

Here is how you could use it using the dynamic api style:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withDefaultValue,indent=0]
----

Similarly, you might want such a specification using the annotation style. Here is an example using an interface
specification:

[source,groovy]
----
include::../../testFixtures/groovy/cli/WithDefaultValueI.groovy[tags=withDefaultValueInterfaceSpec,indent=0]
----

Which would be used like this:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withDefaultValueInterface,indent=0]
----

You can also use the `defaultValue` annotation attribute when using annotations with an instance,
though it's probably just as easy to provide an initial value for the property (or backing field).

===== Use with `TypeChecked`

The dynamic api style of using `CliBuilder` is inherently dynamic but you have a few options
should you want to make use of Groovy's static type checking capabilities. Firstly, consider using the
annotation style, for example, here is an interface option specification:

[source,groovy]
----
include::../../testFixtures/groovy/cli/TypeCheckedI.groovy[tags=withTypeCheckedInterfaceSpec,indent=0]
----

And it can be used in combination with `@TypeChecked` as shown here:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withTypeCheckedInterface,indent=0]
----

Secondly, there is a feature of the dynamic api style which offers some support. The definition statements
are inherently dynamic but actually return a value which we have ignored in earlier examples.
The returned value is in fact a `TypedOption<Type>` and special `getAt` support allows the options
to be interrogated using the typed option, e.g. `options[savedTypeOption]`. So, if you have statements
similar to these in a non type checked part of your code:

[source,groovy]
----
def cli = new CliBuilder()
TypedOption<Integer> age = cli.a(longOpt: 'age', type: Integer, 'some age option')
----

Then, the following statements can be in a separate part of your code which is type checked:

[source,groovy]
----
def args = '--age 21'.split()
def options = cli.parse(args)
int a = options[age]
assert a == 21
----

Finally, there is one additional convenience method offered by `CliBuilder` to even allow the
definition part to be type checked. It is a slightly more verbose method call. Instead of using
the short name (the _opt_ name) in the method call, you use a fixed name of `option` and
supply the `opt` value as a property. You must also specify the type directly as shown in
the following example:

[source,groovy]
----
include::../../testFixtures/groovy/cli/CliBuilderTestCase.groovy[tags=withTypeChecked,indent=0]
----

===== Advanced CLI Usage

[NOTE]
===============================
*NOTE* Advanced CLI features

`CliBuilder` can be thought of as a Groovy friendly wrapper on top of either
https://github.com/remkop/picocli[picocli] or https://commons.apache.org/proper/commons-cli/[Apache Commons CLI].
If there is a feature not provided by `CliBuilder` that you know is supported in the underlying
library, the current `CliBuilder` implementation (and various Groovy language features) make it easy for you
to call the underlying library methods directly. Doing so is a pragmatic way to leverage the Groovy-friendly
syntax offered by `CliBuilder` and yet still access some of the underlying library's advanced features.
A word of caution however; future versions of `CliBuilder` could potentially use another underlying library
and in that event, some porting work may be required for your Groovy classes and/or scripts.
===============================

====== Apache Commons CLI

As an example, here is some code for making use of Apache Commons CLI's grouping mechanism:

[source,groovy]
----
import org.apache.commons.cli.*

def cli = new CliBuilder()
cli.f longOpt: 'from', 'f option'
cli.u longOpt: 'until', 'u option'
def optionGroup = new OptionGroup()
optionGroup.with {
  addOption cli.option('o', [longOpt: 'output'], 'o option')
  addOption cli.option('d', [longOpt: 'directory'], 'd option')
}
cli.options.addOptionGroup optionGroup
assert !cli.parse('-d -o'.split()) // <1>
----
<1> The parse will fail since only one option from a group can be used at a time.

====== Picocli

Below are some features available in the picocli version of `CliBuilder`.

*New property: errorWriter*

When users of your application give invalid command line arguments,
CliBuilder writes an error message and the usage help message to the `stderr` output stream.
It doesn't use the `stdout` stream to prevent the error message from being parsed when your program's
output is used as input for another process.
You can customize the destination by setting the `errorWriter` to a different value.

On the other hand, `CliBuilder.usage()` prints the usage help message to the `stdout` stream.
This way, when users request help (e.g. with a `--help` parameter),
they can pipe the output to a utility like `less` or `grep`.

You can specify different writers for testing.
_Be aware that for backwards compatibility, setting the `writer` property to a different value
will set *both* the `writer` and the `errorWriter` to the specified writer._

*ANSI colors*

The picocli version of CliBuilder renders the usage help message in ANSI colors on supported platforms automatically.
If desired you can http://picocli.info/#_usage_help_with_styles_and_colors[customize] this.
(An example follows below.)

*New property: name*

As before, you can set the synopsis of the usage help message with the `usage` property.
You may be interested in a small improvement:
if you only set the command `name`, a synopsis will be generated automatically,
with repeating elements followed by `...` and optional elements surrounded with `[` and `]`.
(An example follows below.)

*New property: usageMessage*

This property exposes a `UsageMessageSpec` object from the underlying picocli library,
which gives fine-grained control over various sections of the usage help message. For example:

[source,groovy]
----
include::../../../subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=withUsageMessageSpec,indent=0]
----
Gives this output:

image:{reldir_root}/assets/img/usageMessageSpec.png[]

*Property: parser*

The `parser` property gives access to the picocli `ParserSpec` object that can be used to customize the parser behavior.

This can be useful when the `CliBuilder` options to control the parser are not fine-grained enough.
For example, for backward compatibility with the Commons CLI implementation of `CliBuilder`, by default `CliBuilder` stops looking for options when an unknown option is encountered, and subsequent command line arguments are treated as positional parameters.
`CliBuilder` provides a `stopAtNonOption` property, and by setting this to `false` you can make the parser more strict, so an unknown option results in `error: Unknown option: '-x'`.

But what if you want to treat unknown options as positional parameters, and still process subsequent command line arguments as options?

This can be accomplished with the `parser` property.
For example:

[source,groovy]
----
def cli = new CliBuilder()
cli.parser.stopAtPositional(false)
cli.parser.unmatchedOptionsArePositionalParams(true)
// ...
def opts = cli.parse(args)
// ...
----

See the http://picocli.info/apidocs/picocli/CommandLine.Model.ParserSpec.html[documentation] for details.

*Map options*

Finally, if your application has options that are key-value pairs, you may be interested in picocli's support for maps. For example:

[source,groovy]
----
include::../../../subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=mapOptionImports,indent=0]

include::../../../subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=mapOption,indent=0]
----
<1> Previously, `key=value` pairs were split up into parts and added to a list
<2> Picocli map support: simply specify `Map` as the type of the option
<3> You can even specify the type of the map elements
<4> To compare, let's specify two key-value pairs for each option
<5> Previously, all key-value pairs end up in a list and it is up to the application to work with this list
<6> Picocli returns the key-value pairs as a `Map`
<7> Both keys and values of the map can be strongly typed

*Controlling the Picocli version*

To use a specific version of picocli, add a dependency to that version in your build configuration.
If running scripts using a pre-installed version of Groovy, use the `@Grab` annotation to control the version of picocli to use in `CliBuilder`.

[source,groovy]
----
@GrabConfig(systemClassLoader=true)
@Grab('info.picocli:picocli:4.2.0')
import groovy.cli.picocli.CliBuilder

def cli = new CliBuilder()
----

==== ObjectGraphBuilder

`ObjectGraphBuilder` is a builder for an arbitrary graph of beans that
follow the JavaBean convention. It is in particular useful for creating test data.

Let's start with a list of classes that belong to your domain:

[source,groovy]
----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=domain_classes,indent=0]
----

Then using `ObjectGraphBuilder` building a `Company` with three employees is as
easy as:

[source,groovy]
----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=builder_example,indent=0]
----
<1> creates a new object graph builder
<2> sets the classloader where the classes will be resolved
<3> sets the base package name for classes to be resolved
<4> creates a `Company` instance
<5> with 3 `Employee` instances
<6> each of them having a distinct `Address`

Behind the scenes, the object graph builder:

* will try to match a node name into a `Class`, using a default `ClassNameResolver` strategy that requires a package name
* then will create an instance of the appropriate class using a default `NewInstanceResolver` strategy that calls a no-arg constructor
* resolves the parent/child relationship for nested nodes, involving two other strategies:
** `RelationNameResolver` will yield the name of the child property in the parent, and the name of the parent property
in the child (if any, in this case, `Employee` has a parent property aptly named `company`)
** `ChildPropertySetter` will insert the child into the parent taking into account if the child belongs to a `Collection`
 or not (in this case `employees` should be a list of `Employee` instances in `Company`).

All 4 strategies have a default implementation that work as expected if
the code follows the usual conventions for writing JavaBeans. In case any of your beans or objects do not follow the convention
you may plug your own implementation of each strategy. For example imagine that you need to build a class which is
immutable:

[source,groovy]
----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=immutable_class,indent=0]
----

Then if you try to create a `Person` with the builder:

[source,groovy]
----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=immutable_fail_runtime,indent=0]
----

It will fail at runtime with:

----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=expected_error_immutable,indent=0]
----

Fixing this can be done by changing the new instance strategy:

[source,groovy]
----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=newinstanceresolver,indent=0]
----

`ObjectGraphBuilder` supports ids per node, meaning
that you can store a reference to a node in the builder. This is
useful when multiple objects reference the same instance. Because a
property named `id` may be of business meaning in some domain models
`ObjectGraphBuilder` has a strategy named `IdentifierResolver` that you
may configure to change the default name value. The same may
happen with the property used for referencing a previously saved
instance, a strategy named `ReferenceResolver` will yield the
appropriate value (default is `refId'):

[source,groovy]
----
include::../test/builder/ObjectGraphBuilderTest.groovy[tags=test_id,indent=0]
----
<1> an address can be created with an `id`
<2> an employee can reference the address directly with its id
<3> or use the `refId` attribute corresponding to the `id` of the corresponding address

Its worth mentioning that you cannot modify the properties of a
referenced bean.

==== JmxBuilder

See <<{jmx}#jmx_jmxbuilder,Working with JMX - JmxBuilder>> for details.

==== FileTreeBuilder

gapi:groovy.util.FileTreeBuilder[FileTreeBuilder] is a builder for generating a file directory structure from a specification. For example, to create the following tree:

---------
 src/
  |--- main
  |     |--- groovy
  |            |--- Foo.groovy
  |--- test
        |--- groovy
               |--- FooTest.groovy
---------

You can use a `FileTreeBuilder` like this:

[source,groovy]
----
include::../test/builder/FileTreeBuilderTest.groovy[tags=example,indent=0]
----

To check that everything worked as expected we use the following `assert`s:

[source,groovy]
----
include::../test/builder/FileTreeBuilderTest.groovy[tags=example_assert,indent=0]
----

`FileTreeBuilder` also supports a shorthand syntax:

[source,groovy]
----
include::../test/builder/FileTreeBuilderTest.groovy[tags=shorthand_syntax,indent=0]
----

This produces the same directory structure as above, as shown by these `assert`s:

[source,groovy]
----
include::../test/builder/FileTreeBuilderTest.groovy[tags=shorthand_syntax_assert,indent=0]
----

=== Creating a builder

While Groovy has many built-in builders, the builder pattern is so common,
you will no doubt eventually come across a building requirement that
hasn't been catered for by those built-in builders.
The good news is that you can build your own.
You can do everything from scratch by relying on Groovy's
metaprogramming capabilities. Alternatively, the `BuilderSupport`
and `FactoryBuilderSupport` classes make designing your own
builders much easier.

==== BuilderSupport

One approach to building a builder is to subclass `BuilderSupport`.
With this approach, the general idea is to override one or more of a number of
_lifecycle_ methods including `setParent`, `nodeCompleted` and some or
all of the `createNode` methods from the `BuilderSupport` abstract class.

As an example, suppose we want to create a builder of
tracking athletic training programs. Each program is made
up of a number of sets and each set has its own steps.
A step might itself be a set of smaller steps.
For each `set` or `step`, we might wish to record
the `distance` required (or `time`), whether to `repeat`
the steps a certain number of times, whether to take a `break`
between each step and so forth.

For the simplicity of this example, we'll capture the training
programming using maps and lists. A set has a list of steps.
Information like `repeat` count or `distance` will be tracked
in a map of attributes for each step and set.

The builder implementation is as follows:

* Override a couple of the `createNode` methods.
We'll create a map capturing the set name, an empty list of steps,
and potentially some attributes.
* Whenever we complete a node we'll add the node to the list of steps
for the parent (if any).

The code looks like this:

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=define_builder1,indent=0]
----

Next, we'll write a little helper method which recursively
adds up the distances of all substeps, accounting for repeated steps
as needed.

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=define_total_helper1,indent=0]
----

Finally, we can now use our builder and helper method to create a
swimming training program and check its total distance:

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=use_builder1,indent=0]
----

==== FactoryBuilderSupport

A second approach to building a builder is to subclass `FactoryBuilderSupport`.
This builder has similar goals to `BuilderSupport` but with extra features
to simplify domain class construction.

With this approach, the general idea is to override one or more of a number of
_lifecycle_ methods including `resolveFactory`, `nodeCompleted` and `postInstantiate` methods from the `FactoryBuilderSupport` abstract class.

We'll use the same example as for the previous `BuilderSupport` example;
a builder of tracking athletic training programs.

For this example, rather than capturing the training
programming using maps and lists, we'll use some simple domain classes.

The builder implementation is as follows:

* Override the `resolveFactory` method to return a special
factory which returns classes by capitalizing the names used in our mini DSL.
* Whenever we complete a node we'll add the node to the list of steps
for the parent (if any).

The code, including the code for the special factory class, looks like this:

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=define_builder2,indent=0]
----

Rather than using lists and maps, we'll have some simple domain classes
and related traits:

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=define_domain_classes2,indent=0]
----

Just like for the `BuilderSupport` example, it is useful to have a helper method
to calculate the total distance covered during the training session.
The implementation is very similar to our earlier example, but is adjusted
to work well with our newly defined traits.

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=define_total_helper2,indent=0]
----

Finally, we can now use our new builder and helper methods to create a
cycling training program and check its total distance:

[source,groovy]
----
include::../test/builder/BuilderSpecTest.groovy[tags=use_builder2,indent=0]
----

---

### Src Spec Doc Core Gdk (`src/spec/doc/core-gdk.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////

= Groovy Development Kit


include::_working-with-io.adoc[leveloffset=+1]

include::_working-with-collections.adoc[leveloffset=+1]

include::_working-with-arrays.adoc[leveloffset=+1]

include::../../../subprojects/groovy-dateutil/src/spec/doc/_working-with-dateutil-types.adoc[leveloffset=+1]

include::../../../subprojects/groovy-datetime/src/spec/doc/_working-with-datetime-types.adoc[leveloffset=+1]

== Handy utilities

=== ConfigSlurper

`ConfigSlurper` is a utility class for reading configuration files defined in the form of Groovy scripts. Like it is
the case with Java `*.properties` files, `ConfigSlurper` allows a dot notation. But in addition, it allows for Closure scoped
configuration values and arbitrary object types.

[source,groovy]
----
include::../test/gdk/ConfigSlurperTest.groovy[tags=arbitrary_types,indent=0]
----
<1> Usage of the dot notation
<2> Usage of Closure scopes as an alternative to the dot notation

As can be seen in the above example, the `parse` method can be used to retrieve `groovy.util.ConfigObject` instances. The
`ConfigObject` is a specialized `java.util.Map` implementation that either returns the configured value or a new `ConfigObject`
instance but never `null`.

[source,groovy]
----
include::../test/gdk/ConfigSlurperTest.groovy[tags=never_null,indent=0]
----
<1> `config.test` has not been specified yet it returns a `ConfigObject` when being called.

In the case of a dot being part of a configuration variable name, it can be escaped by using single or double quotes.

[source,groovy]
----
include::../test/gdk/ConfigSlurperTest.groovy[tags=escape_dot,indent=0]
----

In addition, `ConfigSlurper` comes with support for `environments`. The `environments` method can be used to hand over
a Closure instance that itself may consist of a several sections. Let's say we wanted to create a particular configuration
value for the development environment. When creating the `ConfigSlurper` instance we can use the `ConfigSlurper(String)`
constructor to specify the target environment.

[source,groovy]
----
include::../test/gdk/ConfigSlurperTest.groovy[tags=environments,indent=0]
----

[NOTE]
The `ConfigSlurper` environments aren't restricted to any particular environment names. It solely depends on the
`ConfigSlurper` client code what value are supported and interpreted accordingly.

The `environments` method is built-in but the `registerConditionalBlock` method can be used to register other method names
in addition to the `environments` name.

[source,groovy]
----
include::../test/gdk/ConfigSlurperTest.groovy[tags=custom_environments,indent=0]
----
<1> Once the new block is registered `ConfigSlurper` can parse it.

For Java integration purposes the `toProperties` method can be used to convert the `ConfigObject` to a `java.util.Properties`
object that might be stored to a `*.properties` text file. Be aware though that the configuration values are converted to
`String` instances during adding them to the newly created `Properties` instance.

[source,groovy]
----
include::../test/gdk/ConfigSlurperTest.groovy[tags=properties,indent=0]
----

=== Expando

The `Expando` class can be used to create a dynamically expandable object. Despite its name it does not use the
`ExpandoMetaClass` underneath. Each `Expando` object represents a standalone, dynamically-crafted instance that can be
extended with properties (or methods) at runtime.

[source,groovy]
----
include::../test/gdk/ExpandoTest.groovy[tags=expando_property,indent=0]
----

A special case occurs when a dynamic property registers a `Closure` code block. Once being registered it can be invoked
as it would be done with a method call.

[source,groovy]
----
include::../test/gdk/ExpandoTest.groovy[tags=expando_method,indent=0]
----

=== Observable list, map and set

Groovy comes with observable lists, maps and sets. Each of these collections trigger `java.beans.PropertyChangeEvent` events when elements
are added, removed or changed. Note that a `PropertyChangeEvent` is not only signalling that a certain event has
 occurred, moreover, it holds information on the property name and the old/new value a certain property has been changed to.

Depending on the type of change that has happened, observable collections might fire more specialized `PropertyChangeEvent`
 types. For example, adding an element to an observable list fires an `ObservableList.ElementAddedEvent` event.

[source,groovy]
----
include::../test/gdk/ObservableTest.groovy[tags=observable_list,indent=0]
----
<1> Declares a `PropertyChangeEventListener` that is capturing the fired events
<2> `ObservableList.ElementEvent` and its descendant types are relevant for this listener
<3> Creates an `ObservableList` from the given list
<4> Registers the listener
<5> Triggers an `ObservableList.ElementAddedEvent` event

[NOTE]
Be aware that adding an element in fact causes two events to be triggered. The first is of type `ObservableList.ElementAddedEvent`,
the second is a plain `PropertyChangeEvent` that informs listeners about the change of property `size`.

The `ObservableList.ElementClearedEvent` event type is another interesting one. Whenever multiple
 elements are removed, for example when calling `clear()`, it holds the elements being removed from the list.

[source,groovy]
----
include::../test/gdk/ObservableTest.groovy[tags=observable_list_clear,indent=0]
----

To get an overview of all the supported event types the reader is encouraged to have a look at the JavaDoc documentation
or the source code of the observable collection in use.

`ObservableMap` and `ObservableSet` come with the same concepts as we have seen for `ObservableList` in this section.

---

### Src Spec Doc Core Getting Started (`src/spec/doc/core-getting-started.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////
ifndef::groovy-console[]
:groovy-console: groovy-console.adoc
endif::[]

= Getting started

== Download

From the https://groovy.apache.org/download.html[download] page,
you will be able to download the distribution (binary and source),
the Windows installer (a community artifact) and the documentation for **Groovy**.

For a quick and effortless start on Mac OSX, Linux, WSL2 or Cygwin, you can use https://sdkman.io/[SDKMAN!]
(The Software Development Kit Manager) to download and configure any **Groovy** version of your choice.
Basic <<SDKMAN,instructions>> can be found below.

=== Stable

- **Download zip**: https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/apache-groovy-binary-{groovy-full-version}.zip[**Binary Release**] | https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/apache-groovy-src-{groovy-full-version}.zip[Source Release]
- **Download documentation**: https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/apache-groovy-docs-{groovy-full-version}.zip[**JavaDoc and zipped online documentation**]
- **Combined binary / source / documentation bundle**: https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/apache-groovy-sdk-{groovy-full-version}.zip[**Distribution bundle**]

You can learn more about this version in the https://groovy-lang.org/releasenotes/groovy-{groovy-short-version}.html[release notes] or in the https://groovy-lang.org/changelogs/changelog-{groovy-full-version}.html[changelog].

If you plan on using invokedynamic support, link:invokedynamic-support.html[read those notes].

=== Snapshots

For those who want to test the very latest versions of Groovy and live on the bleeding edge, you can use our https://repository.apache.org/content/groups/snapshots/org/apache/groovy[snapshot builds].
As soon as a build succeeds on our continuous integration server a snapshot is deployed to this repository.
These snapshots are not official releases and are intended for integration testing by the development
community prior to official versions being released. We welcome any feedback.

=== Prerequisites

Groovy {groovy-short-version} requires Java 17+ with support for up to Java 25.

Various Groovy CI servers run the test suite (with more than 10000 tests) across numerous versions of Java.
Those servers are also useful to look at to confirm supported Java versions for different Groovy releases.

== Maven Repository

If you wish to embed Groovy in your application, you may just prefer to point your build
to your favourite maven repository or the Groovy https://groovy.jfrog.io/artifactory/libs-release-local/[artifactory instance].
Please see the https://groovy.apache.org/download.html#buildtools[download page] for available modules for each Groovy version.

[[SDKMAN]]
== SDKMAN! (The Software Development Kit Manager)

This tool makes installing Groovy on any Bash platform (Mac OSX, Linux, Cygwin, Solaris or FreeBSD) very easy.

Simply open a new terminal and enter:

[source,shell]
----
$ curl -s "https://get.sdkman.io" | bash
----

Follow the instructions on-screen to complete installation.

Open a new terminal or type the command:

[source,shell]
----
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
----

Then install the latest stable Groovy:

[source,shell]
----
$ sdk install groovy
----

After installation is complete and you've made it your default version, test it with:

[source,shell]
----
$ groovy -version
----

That's all there is to it!

== Other ways to get Groovy

=== Installation on Mac OS X

==== MacPorts

If you're on macOS and have https://www.macports.org[MacPorts] installed, you can run:

[source,shell]
----
sudo port install groovy
----

==== Homebrew

If you're on macOS and have https://brew.sh/[Homebrew] installed, you can run:

[source,shell]
----
brew install groovy
----

=== Installation on Windows

If you're on Windows, you can also use the https://groovy.jfrog.io/artifactory/dist-release-local/groovy-windows-installer/[Windows installer].

=== Other Distributions

You may download other distributions of Groovy from the ASF
https://archive.apache.org/dist/groovy/[archive repository]
or from the Groovy
https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/[artifactory instance] (also includes pre-ASF versions).

=== Source Code

If you prefer to live on the bleeding edge, you can also grab the https://github.com/apache/groovy[source code from GitHub].

=== IDE plugin

If you are an IDE user, you can just grab the latest link:tools-ide.html[IDE plugin] and follow the plugin installation instructions.

== Install Binary

These instructions describe how to install a binary distribution of **Groovy**:

* https://groovy.apache.org/download.html[Download] a binary distribution of Groovy and unpack it into some folder on your local file system.
* Set your `GROOVY_HOME` environment variable to the directory where you unpacked the distribution.
* Add `GROOVY_HOME/bin` to your `PATH` environment variable.
* Set your `JAVA_HOME` environment variable to point to your JDK. On OS X this is `/Library/Java/Home`, on other unixes its often `/usr/java` etc. If you've already installed tools like Ant or Maven you've probably already done this step.

You should now have Groovy installed properly. You can test this by typing the following in a command shell:

[source,shell]
----
groovysh
----

Which should create an interactive groovy shell where you can type Groovy statements. Or to run the <<{groovy-console}#title-heading,Swing interactive console>> type:

[source,shell]
----
groovyConsole
----

To run a specific Groovy script type:

[source,shell]
----
groovy SomeScript
----

---

### Src Spec Doc Core Grammar (`src/spec/doc/core-grammar.adoc`)

//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

//////////////////////////////////////////
ifndef::core-syntax[]
:core-syntax: core-syntax.adoc
endif::[]
ifndef::core-operators[]
:core-operators: core-operators.adoc
endif::[]
ifndef::core-program-structure[]
:core-program-structure: core-program-structure.adoc
endif::[]
ifndef::core-semantics[]
:core-semantics: core-semantics.adoc
endif::[]

[[groovy-grammar]]
= Grammar

This chapter is a complete specification of the Groovy language syntax
recognised at compilation phase `PARSING`. It is written for readers who
need a closed, citable grammar -- language researchers, tool authors,
and implementers. Informal syntax, examples, and runtime meaning live
in <<{core-syntax}#_syntax,Syntax>>,
<<{core-operators}#groovy-operators,Operators>>,
<<{core-program-structure}#_program_structure,Program structure>>, and
<<{core-semantics}#_semantics,Semantics>>.

The executable grammar is `src/antlr/GroovyLexer.g4` and
`src/antlr/GroovyParser.g4`. This chapter is a complete EBNF projection
of those files: every parser rule, lexer token, fragment, and mode
appears. The `.g4` files remain the implementation source of truth --
if a production here and a rule there disagree, the rule wins until
this chapter is updated.

== Status and scope

Groovy's surface syntax is **not a pure context-free grammar**. The
specification has three layers:

. a *lexical context machine* (lexer modes, grouping stack, newline
  hiding, token-type rewrites);
. a *CFG skeleton* in Groovy Spec EBNF, using the ANTLR parser rule
  names as nonterminals;
. a finite list of *restrictions* R1, R2, ... that filter or
  disambiguate that skeleton (the analogue of JLS static restrictions /
  ECMA-262 early errors).

Lexer alternatives are *ordered* (first match among those whose
predicates hold, then longest match). Parser alternatives of
`expression` are ordered by precedence (earlier binds tighter).
Conversion of the parse tree to AST (`AstBuilder`, compilation phase
`CONVERSION`), semantic analysis, type checking, and AST transforms are
out of scope. The CFG is an intentional over-approximation: some
programs that match it are rejected later. Those cases are listed
under <<grammar-overapprox>> rather than hidden by inventing extra
productions.

This chapter does **not** re-introduce parser error alternatives for
missing `)`, `]`, or `}` (GROOVY-9588). Recognition failures share the
diagnostic path described in `ARCHITECTURE.md`.

[[grammar-notation]]
== Notation

[[grammar-ebnf-legend]]
=== Groovy Spec EBNF

Productions are written in `[source,ebnf]` blocks. The operator set is
W3C EBNF; the names are ANTLR 4 rule names.

[cols="1,2,2", options="header"]
|===
| Construct
| Meaning
| Example

| `N ::= ...`
| Production for nonterminal `N`
| `sep ::= (NL \| ';')+`

| `A \| B`
| Alternation (one of)
| `'class' \| 'interface'`

| `( ... )`
| Grouping
| `'static'? qualifiedName`

| `X?`
| Optional (zero or one)
| `packageDeclaration?`

| `X*`
| Kleene star (zero or more)
| `NL*`

| `X+`
| One or more
| `(NL \| ';')+`

| `'foo'`
| Terminal with that exact spelling (see <<grammar-vocabulary>>)
| `'import'`

| `Identifier`
| Terminal with no unique spelling (token name)
| `GStringBegin`

| `/* R12 */`
| This alternative is subject to restriction R12. Lexer fragments with
  such marks are *ordered*: try earlier alternatives first.
| `'$' /* R2 fails */`

| `fragment F`
| Lexer fragment: not a token, only used by other lexer productions
| `fragment Digits`

| `<MODE>`
| Lexer start condition (mode). The production applies only in that mode
| `<DQ_GSTRING_MODE>`
|===

Concatenation is juxtaposition (W3C, not ISO 14977 comma). Square
brackets and braces are Groovy terminals (lists, closures), so
ISO 14977 optional/repetition brackets are not used.

A bare `A | B` in a parser production is unordered alternation (the
CFG skeleton). Where the g4 is ordered -- lexer rules, lexer
fragments with predicates, and predicated parser alternatives -- this
chapter annotates the restricted alternative with `/* R */`.
Reconstructing a lexer from the unordered `|` of a fragment without
those comments yields a different language.

There is **no** `nls` nonterminal in `GroovyParser.g4`. Optional
newlines are written `NL*` in situ. The statement separator is `sep`.

Left-recursive `expression` is a CFG production. Associativity that
ANTLR marks with `<assoc=right>` is recorded in the precedence table,
not with a special EBNF operator. Earlier alternatives of
`expression` bind tighter (ANTLR 4 left-recursion).

ANTLR parameterized rules (`classBody[int t]`,
`expressionList[boolean canSpread]`) are not parameterized EBNF.
Syntactic parameters become named specialisations plus
<<grammar-parameter-bijection>>; parameters that exist only to tag the
CST for `AstBuilder` are notes, not syntax.

Parser alternative labels (`#castExprAlt`, ...) are visitor names, not
nonterminals.

[[grammar-vocabulary]]
== Terminal vocabulary

=== Keywords and identifier sets

The lexer always emits a dedicated token for a keyword spelling (except
`val` when R5 disables it). The parser then *re-accepts* some of those
tokens as names.

Four concentric sets:

* `identifier` -- unquoted names, labels, type names, unquoted method
  names.
* `keywords` -- after `.` (`namePart`), as map keys, as annotation
  element names.
* `qualifiedNameElement` -- package / import pieces, additionally
  `'def'` `'in'` `'as'` `'trait'`.
* `methodName` -- `identifier` or `stringLiteral` (quoted names of any
  spelling, including reserved words).

`className` is only `CapitalizedIdentifier`.

[cols="1,1,1,1,2", options="header"]
|===
| Lexeme
| Token
| In `identifier`?
| In `keywords`?
| Notes

| `abstract` `assert` `break` `case` `catch` `class` `continue` `default` `do` `else` `enum` `extends` `final` `finally` `for` `if` `implements` `import` `instanceof` `interface` `native` `new` `package` `return` `static` `strictfp` `super` `switch` `synchronized` `this` `throw` `throws` `transient` `try` `volatile` `while`
| matching keyword token
| no
| yes
| reserved

| `public` `protected` `private`
| `PUBLIC` `PROTECTED` `PRIVATE`
| no
| yes
| reserved

| `void` and primitives
| `VOID` / `BuiltInPrimitiveType`
| no
| yes
| primitives are one token type (see below)

| `true` `false` `null`
| `BooleanLiteral` / `NullLiteral`
| no
| yes
| reserved words, not `identifier`

| `def`
| `DEF`
| no
| yes
| also `qualifiedNameElement`; a modifier, not a type production

| `const` `goto` `threadsafe`
| `CONST` `GOTO` `THREADSAFE`
| no
| yes
| reserved and unused. Not in `identifier`: a bare use is a *parse*
  error. In `keywords`, so legal after `.`, as a map key, and as an
  annotation element name.

| `non-sealed`
| `NON_SEALED`
| no
| yes
| one token, including the hyphen

| `as` `in` `trait` `record` `sealed` `permits` `var` `yield` `async` `await` `defer` `module`
| matching token
| **yes**
| `module`: **no**; others: yes
| contextual. `module` is in `identifier` only (for `import module`)

| `val`
| `VAL` or `Identifier` (R5)
| **yes** (always: token `VAL` or `Identifier`)
| **yes** only when the token is `VAL`
| feature flag `groovy.val.enabled` (default `true`). When false, `val`
  is `Identifier` and is therefore not a `variableModifier`.
|===

`BuiltInPrimitiveType` is a **single** token type whose spellings are
the fragments `boolean` `char` `byte` `short` `int` `long` `float`
`double`. Those fragments are not independent tokens.

`it` is **not** a token. Implicit closure parameters are semantic.

The tutorial keyword tables in <<{core-syntax}#_syntax,Syntax>> are a
user-facing cut. This chapter follows the g4. In particular the grammar
has `yield` (not `yields`), and `async` / `await` / `defer` / `module` /
`val` as tokens.

=== Operators and separators

Lexer tokens with unique spelling (parser productions quote the
lexeme):

[cols="2,1,3", options="header"]
|===
| Lexeme
| Token
| Role

| `..` `<..` `..<` `<..<`
| `RANGE_INCLUSIVE` `RANGE_EXCLUSIVE_LEFT` `RANGE_EXCLUSIVE_RIGHT` `RANGE_EXCLUSIVE_FULL`
| ranges (shift precedence)

| `*.` `?.` `??.` `.&` `::`
| `SPREAD_DOT` `SAFE_DOT` `SAFE_CHAIN_DOT` `METHOD_POINTER` `METHOD_REFERENCE`
| path operators. `'??.'` is syntax even if omitted from the operators tutorial

| `?[`
| `SAFE_INDEX`
| safe index; pushes grouping (R9)

| `?:` `?=`
| `ELVIS` `ELVIS_ASSIGN`
| elvis / elvis-assign

| `=~` `==~`
| `REGEX_FIND` `REGEX_MATCH`
| regex find / match

| `**` `**=`
| `POWER` `POWER_ASSIGN`
| power

| `<=>` `===` `!==` `==>`
| `SPACESHIP` `IDENTICAL` `NOT_IDENTICAL` `IMPLIES`
|

| `->`
| `ARROW`
| closure / lambda / switch-expression arrow

| `!instanceof` `!in`
| `NOT_INSTANCEOF` `NOT_IN`
| R6

| `(` `)` `{` `}` `[` `]`
| `LPAREN` `RPAREN` `LBRACE` `RBRACE` `LBRACK` `RBRACK`
| grouping; each opener `pushMode(DEFAULT_MODE)`

| `;` `,` `.` `@` `...`
| `SEMI` `COMMA` `DOT` `AT` `ELLIPSIS`
|

| `=` `>` `<` `!` `~` `?` `:` `==` `\<=` `>=` `!=` `&&` `\|\|` `++` `--` `+` `-` `*` `/` `&` `\|` `^` `%`
| `ASSIGN` `GT` `LT` `NOT` `BITNOT` `QUESTION` `COLON` `EQUAL` `LE` `GE` `NOTEQUAL` `AND` `OR` `INC` `DEC` `ADD` `SUB` `MUL` `DIV` `BITAND` `BITOR` `XOR` `MOD`
| `/` as an *operator* is `DIV`, never written `'/'` in parser EBNF (R1)

| `+=` `-=` `*=` `/=` `&=` `\|=` `^=` `%=` `<<=` `>>=` `>>>=`
| matching `*_ASSIGN` tokens
| shift *assignments* are tokens; shift *operators* are not
|===

There are **no** `LSHIFT` / `RSHIFT` / `URSHIFT` lexer tokens. The
parser composes `'<' '<'`, `'>' '>'`, `'>' '>' '>'` so
`List<List<T>>` can close.

=== Literals as token names

`IntegerLiteral`, `FloatingPointLiteral`, `BooleanLiteral`,
`NullLiteral`, `StringLiteral`, `GStringBegin`, `GStringPart`,
`GStringEnd`, `GStringPathPart`, `Identifier`, `CapitalizedIdentifier`,
`NL`.

Quote style of an interpolating string is **not** a parser token:
`TdqGStringBegin`, `SlashyGStringBegin`, and
`DollarSlashyGStringBegin` are rewritten to `GStringBegin` (similarly
`GStringPart` / `GStringEnd`).

[[grammar-lexical]]
== Lexical structure

=== Input elements

The lexer produces a stream of default-channel tokens for the parser,
plus skipped or hidden trivia. Successful tokenisation never takes the
`UNEXPECTED_CHAR` / unclosed-comment / invalid-octal paths
(`AbstractLexer`); those are diagnostics, not language
(<<grammar-invalid>>).

=== White space and line escapes

[source,ebnf]
----
WS ::= ([ \t]+ | LineEscape+)          /* skip */

fragment LineEscape     ::= '\\' LineTerminator
fragment LineTerminator ::= '\r'? '\n' | '\r'
----

Spaces and tabs are skipped. A backslash immediately followed by a line
terminator is also skipped (line continuation) and is **not** `NL`.

=== Line terminators, comments, shebang

[source,ebnf]
----
NL ::= LineTerminator                  /* then R9 */

SL_COMMENT ::=
    '//' ~[\r\n\uFFFF]*                /* -> type(NL); then R9 */

ML_COMMENT ::=
    '/*' .*? ('*/' | EOF)              /* -> type(NL); then R10.
                                          unclosed: diagnostic at opener */

SH_COMMENT ::=                         /* skip; R11 */
    '#!' ShCommand (LineTerminator '#!' ShCommand)*

fragment ShCommand ::= ~[\r\n\uFFFF]*
----

There is no comment channel. `//` and `/* ... */` are rewritten to
token type `NL`, so a comment can act as a statement separator when it
stays on the default channel.

Groovydoc (`/** ... */` and runtime `/**@ ... */`) is **not** a
distinct token. It is `ML_COMMENT`; `GroovydocManager` attaches it
after parse. Groovydoc *tag* semantics are excluded.

`SH_COMMENT` is skipped when R11 holds (`tokenIndex == 0`). Leading
skipped `WS` (spaces, tabs, line-escapes) does not increment
`tokenIndex`, so a shebang after leading spaces is still skipped. A
prior *default-channel* token -- including a leading `NL` -- is not
allowed. Extra `#!` lines immediately after a line terminator are
part of the same `SH_COMMENT` token.

=== The grouping stack and newline significance

`(`/`[`/`{`/`?[` record a grouping frame (`enterParen`) and
`pushMode(DEFAULT_MODE)`. The matching closer pops both.

Restriction R9: `NL` (and `SL_COMMENT` rewritten to `NL`) is moved to
the **hidden** channel when the stack top is:

* `'('` whose *preceding default-channel token* is not `'try'`, or
* `'['`, or
* `'?['`.

Newlines inside `{ ... }` are **significant**. Try-with-resources
`try ( ... )` does **not** hide newlines (`TRY` on the `(` frame).
Angle brackets `'<'` / `'>'` do **not** push a grouping frame, which
is why `typeArguments` writes `NL*` explicitly.

`$\{` in a GString also calls `enterParen()` (see
<<grammar-gstring-lexical>>), so the interpolation's `'{'` -- not an
enclosing `'('` / `'['` -- is the stack top while the closure body is
tokenised.

Restriction R10: `/* ... */` remains a visible `NL` only when it is
**not** inside grouping (R9) **and** only whitespace remains until end
of line or file. So `a /*c*/ b` is not two statements; `a /*c*/` then
newline then `b` is.

Inside grouping, hidden `NL` is absent from the parser token stream.
Parser productions still write `NL*` / `sep`; those match only
*visible* `NL`.

`lastTokenType` (used by slashy-string vs `DIV`, R1) is updated only
for default-channel tokens. Hidden newlines do not change it.

=== Identifiers

[source,ebnf]
----
CapitalizedIdentifier ::=
      [A-Z] JavaLetterOrDigit*
    | ~[\u0000-\u007F\uD800-\uDBFF]    /* R7 BMP, uppercase */
      JavaLetterOrDigit*
    | [\uD800-\uDBFF] [\uDC00-\uDFFF]  /* R7 supplementary, uppercase */
      JavaLetterOrDigit*

Identifier ::=
      [a-z$_] JavaLetterOrDigit*
    | ~[\u0000-\u007F\uD800-\uDBFF]    /* R7 BMP, not uppercase */
      JavaLetterOrDigit*
    | [\uD800-\uDBFF] [\uDC00-\uDFFF]  /* R7 supplementary, not uppercase */
      JavaLetterOrDigit*

fragment JavaLetter ::=
      [a-zA-Z$_]
    | ~[\u0000-\u007F\uD800-\uDBFF]    /* R7 BMP start, not ignorable */
    | [\uD800-\uDBFF] [\uDC00-\uDFFF]  /* supplementary start (code point) */

fragment JavaLetterOrDigit ::=
      [a-zA-Z0-9$_]
    | ~[\u0000-\u007F\uD800-\uDBFF]    /* R7 BMP part, not ignorable */
    | [\uD800-\uDBFF] [\uDC00-\uDFFF]  /* supplementary part (code point) */

fragment JavaLetterInGString ::=
    JavaLetter                         /* R8: last consumed char is not '$' */

fragment JavaLetterOrDigitInGString ::=
    JavaLetterOrDigit                  /* R8 */

fragment IdentifierInGString ::=
    JavaLetterInGString JavaLetterOrDigitInGString*
----

ASCII is a predicate-free DFA split (`[A-Z]` vs `[a-z$_]`).
Supplementary-plane letters classify capitalized vs not from the
decoded code point, not `LA(-1)` (a low surrogate is never uppercase;
GROOVY-12398). Identifier-ignorable start and continuation characters
are rejected on the *BMP* path (R7); the supplementary-plane path
tests `Character.isJavaIdentifierStart` / `Part` and case only.
GString identifiers cannot contain `$` (R8).

`$` and `_` are allowed in `Identifier`. A leading `$` or `_` is
always `Identifier`, never `CapitalizedIdentifier`.

This is stricter and more precise than the identifier ranges in the
syntax tutorial.

=== `!in` / `!instanceof` / `val`

See R5 and R6.

=== Numeric literals

[source,ebnf]
----
IntegerLiteral ::=
      (DecimalIntegerLiteral | HexIntegerLiteral
       | OctalIntegerLiteral | BinaryIntegerLiteral)
      Underscore?                      /* trailing '_' is then a diagnostic */

fragment DecimalIntegerLiteral ::= DecimalNumeral IntegerTypeSuffix?
fragment HexIntegerLiteral     ::= HexNumeral     IntegerTypeSuffix?
fragment OctalIntegerLiteral   ::= OctalNumeral   IntegerTypeSuffix?
fragment BinaryIntegerLiteral  ::= BinaryNumeral  IntegerTypeSuffix?
fragment IntegerTypeSuffix     ::= [lLiIgG]
fragment DecimalNumeral        ::= '0' | [1-9] (Digits? | Underscores Digits)
fragment Digits                ::= [0-9] ([0-9_]* [0-9])?
fragment Underscores           ::= '_'+
fragment Underscore            ::= '_'
fragment HexNumeral            ::= '0' [xX] HexDigits
fragment HexDigits             ::= HexDigit ([0-9a-fA-F_]* HexDigit)?
fragment HexDigit              ::= [0-9a-fA-F]
fragment OctalNumeral          ::= '0' '_'* OctalDigits
fragment OctalDigits           ::= [0-7] ([0-7_]* [0-7])?
fragment BinaryNumeral         ::= '0' [bB] BinaryDigits
fragment BinaryDigits          ::= [01] ([01_]* [01])?

FloatingPointLiteral ::=
      (DecimalFloatingPointLiteral | HexadecimalFloatingPointLiteral)
      Underscore?

fragment DecimalFloatingPointLiteral ::=
      Digits? '.' Digits ExponentPart? FloatTypeSuffix?
    | Digits ExponentPart FloatTypeSuffix?
    | Digits FloatTypeSuffix
fragment ExponentPart    ::= [eE] [+-]? Digits
fragment FloatTypeSuffix ::= [fFdDgG]
fragment HexadecimalFloatingPointLiteral ::=
    HexSignificand BinaryExponent FloatTypeSuffix?
fragment HexSignificand ::= HexNumeral '.'? | '0' [xX] HexDigits? '.' HexDigits
fragment BinaryExponent ::= [pP] [+-]? Digits
----

Suffix `G`/`g` is `BigInteger` / `BigDecimal` at conversion, not a
distinct token. Invalid octal (`08`, `09`, ...) and trailing `_` are
lexer diagnostics, not language (<<grammar-invalid>>).

=== Ordinary string literals (`StringLiteral`)

A string with **no** interpolating `$` is `StringLiteral`:

[source,ebnf]
----
StringLiteral ::=
      '"'  DqStringCharacter*  '"'
    | "'"  SqStringCharacter*  "'"
    | '/'  SlashyStringCharacter+ '/'     /* R1; at least one inner char */
    | '"""' TdqStringCharacter* '"""'
    | "'''" TsqStringCharacter* "'''"
    | '$/' DollarSlashyStringCharacter+ '/$'

fragment DqStringCharacter ::= ~["\r\n\\$] | EscapeSequence
fragment SqStringCharacter ::= ~['\r\n\\]  | EscapeSequence
fragment TdqStringCharacter ::=
      ~["\\$]
    | '"' /* R3 */
    | EscapeSequence
fragment TsqStringCharacter ::=
      ~['\\]
    | "'" /* R3 */
    | EscapeSequence
fragment SlashyStringCharacter ::=
      '\\' '/'
    | '$'                 /* R2 fails */
    | ~[/$\u0000]
fragment DollarSlashyStringCharacter ::=
      '$$'
    | '$/$'               /* R4: LA(-4) != '$' */
    | '$/'                /* R4: LA(1) != '$' */
    | '/'                 /* R4: LA(1) != '$' */
    | '$'                 /* R2 fails */
    | ~[/$\u0000]

fragment EscapeSequence ::=
      '\\' [btnfrs"'\\]
    | OctalEscape
    | UnicodeEscape                    /* '\' 'u' HexDigit{4} -- exactly one u */
    | '\\' '$'
    | LineEscape
fragment OctalEscape ::=
      '\\' [0-7]
    | '\\' [0-7] [0-7]
    | '\\' [0-3] [0-7] [0-7]
fragment UnicodeEscape ::=
    '\\' 'u' HexDigit HexDigit HexDigit HexDigit
----

Empty `//` is `SL_COMMENT`, not an empty slashy string (the slashy
alternative requires `SlashyStringCharacter+`). Empty `$/$` is not
`StringLiteral` either.

The g4 comment "Groovy allows 1 or more u's after the backslash" does
**not** match the production: `UnicodeEscape` is exactly one `u`.

[[grammar-gstring-lexical]]
=== GString lexical contexts

An interpolating string is **not** `StringLiteral`. At the first
interpolating `$` the lexer emits `GStringBegin` and enters a mode
machine. The parser later sees only:

[source,ebnf]
----
gstring ::=
    GStringBegin gstringValue (GStringPart gstringValue)* GStringEnd

gstringValue ::=
    gstringPath
  | closure

gstringPath ::=
    identifier GStringPathPart*
----

==== Modes

[cols="1,3", options="header"]
|===
| Mode
| Role

| `DEFAULT_MODE`
| Normal source. Also re-entered for `$\{ ... }` and nested grouping.

| `DQ_GSTRING_MODE`
| Body of `"..."` after the first interpolating `$`

| `TDQ_GSTRING_MODE`
| Body of `"""..."""`

| `SLASHY_GSTRING_MODE`
| Body of `/.../`

| `DOLLAR_SLASHY_GSTRING_MODE`
| Body of `$/.../$`

| `GSTRING_TYPE_SELECTOR_MODE`
| Just after `$`: either `'{'` or an `IdentifierInGString`

| `GSTRING_PATH_MODE`
| After a bare identifier: zero or more `'.' IdentifierInGString`,
  then one-character pushback (`RollBackOne`)
|===

Opening (all in `DEFAULT_MODE`). The last three rules rewrite their
token type to `GStringBegin`; each still pushes its own body mode and
then `GSTRING_TYPE_SELECTOR_MODE`:

[source,ebnf]
----
GStringBegin ::=
    '"' DqStringCharacter* '$'
    /* push DQ_GSTRING_MODE, GSTRING_TYPE_SELECTOR_MODE */

TdqGStringBegin ::=
    '"""' TdqStringCharacter* '$'
    /* type(GStringBegin);
       push TDQ_GSTRING_MODE, GSTRING_TYPE_SELECTOR_MODE */

SlashyGStringBegin ::=                 /* R1; R2 on the interpolating '$' */
    '/' SlashyStringCharacter* '$'
    /* type(GStringBegin);
       push SLASHY_GSTRING_MODE, GSTRING_TYPE_SELECTOR_MODE */

DollarSlashyGStringBegin ::=           /* R2 on the interpolating '$' */
    '$/' DollarSlashyStringCharacter* '$'
    /* type(GStringBegin);
       push DOLLAR_SLASHY_GSTRING_MODE, GSTRING_TYPE_SELECTOR_MODE */
----

Quote bodies accumulate with `-> more` (not parser tokens). Every
body mode has a character rule:

[source,ebnf]
----
<DQ_GSTRING_MODE>
GStringEnd       ::= '"'               /* popMode */
GStringPart      ::= '$'               /* push GSTRING_TYPE_SELECTOR_MODE */
GStringCharacter ::= DqStringCharacter /* more */

<TDQ_GSTRING_MODE>
TdqGStringEnd       ::= '"""'          /* type(GStringEnd), popMode */
TdqGStringPart      ::= '$'            /* type(GStringPart);
                                          push GSTRING_TYPE_SELECTOR_MODE */
TdqGStringCharacter ::= TdqStringCharacter /* more */

<SLASHY_GSTRING_MODE>
SlashyGStringEnd       ::= '$'? '/'    /* type(GStringEnd), popMode */
SlashyGStringPart      ::= '$'         /* R2; type(GStringPart);
                                          push GSTRING_TYPE_SELECTOR_MODE */
SlashyGStringCharacter ::= SlashyStringCharacter /* more */

<DOLLAR_SLASHY_GSTRING_MODE>
DollarSlashyGStringEnd       ::= '/$'  /* type(GStringEnd), popMode */
DollarSlashyGStringPart      ::= '$'   /* R2; type(GStringPart);
                                          push GSTRING_TYPE_SELECTOR_MODE */
DollarSlashyGStringCharacter ::= DollarSlashyStringCharacter /* more */
----

Selector and path:

[source,ebnf]
----
<GSTRING_TYPE_SELECTOR_MODE>
GStringLBrace     ::= '{'
    /* enterParen(); type(LBRACE); popMode; push DEFAULT_MODE */
GStringIdentifier ::= IdentifierInGString
    /* type(Identifier); popMode; push GSTRING_PATH_MODE */

<GSTRING_PATH_MODE>
GStringPathPart ::= '.' IdentifierInGString
RollBackOne     ::= .
    /* popMode. If EOF after '"' or '/', type(GStringEnd);
       else channel HIDDEN. emit() calls rollbackOneChar()
       only when the type is still RollBackOne. */
----

`RollBackOne` is not a parser terminal. When the type remains
`RollBackOne`, `emit()` rolls the input back one character so the
parent GString mode can re-lex it. The EOF-after-`"`/`/` path *is*
the `GStringEnd` token and does **not** roll back.

`gstringPath` is only `identifier` followed by `'.' ident` segments.
A method call in interpolation must be a `closure`:
`"$\{foo.bar()}"`, not `"$foo.bar()"`.

==== How `$\{ ... }` contains real Groovy

`GStringLBrace` records a `'{'` grouping frame (`enterParen()`),
emits `LBRACE`, and pushes `DEFAULT_MODE`. The parser matches
`closure`. So `"$\{ x + 1 }"`, `"$\{ def a = 1; a }"`, and
`"$\{ -> x }"` are all `gstringValue -> closure` syntactically.
Conversion may unwrap a no-arrow single expression; that unwrap is not
this grammar.

Because `'('`, `'['`, `'{'`, and `'?['` all `pushMode(DEFAULT_MODE)`,
an interpolation may contain nested strings and GStrings. That is mode
nesting, not a CFG of characters.

==== Dollar vs interpolation (R2)

In `"..."` and `"""..."""`, every `$` that is not `\$` starts
interpolation.

In `/.../` and `$/.../$`, `$` starts interpolation only if R2 holds.
Therefore `/$5/` and `/$()/` are legal slashy *strings*. The same text
in double quotes is a GString (or a parse failure at the selector).

=== Slashy string vs division vs comment (R1)

Tokenisation of `/` is a three-way (plus comment):

* `//` -> `SL_COMMENT`
* slashy `StringLiteral` / `SlashyGStringBegin` when R1 holds and the
  next character is not `*` (`/*` is `ML_COMMENT`)
* otherwise `DIV`

R1 forbids slashy strings when the previous **default-channel** token
is one of `DEC`, `INC`, `THIS`, `RBRACE`, `RBRACK`, `RPAREN`,
`GStringEnd`, `NullLiteral`, `StringLiteral`, `BooleanLiteral`,
`IntegerLiteral`, `FloatingPointLiteral`, `Identifier`,
`CapitalizedIdentifier`.

Examples: `a++ / b` is division; `list[i] / n` is division;
`x = /foo/` is a slashy string (`ASSIGN` is not in the set).

[[grammar-restrictions]]
== Restrictions

Each restriction cites its implementation site. They are not CFG.

=== Lexical

**R1** (`isRegexAllowed`, `LA(1) != '*'`)::
`/.../` is a slashy string only if the previous default-channel token
is not in the set listed above, and the character after the opening
`/` is not `*`.

**R2** (`isFollowedByJavaLetterInGString`)::
In slashy and dollar-slashy *text* (including the interpolating `$` of
`SlashyGStringBegin` / `DollarSlashyGStringBegin` and the `'$'`
alternative of `SlashyStringCharacter` / `DollarSlashyStringCharacter`),
`$` opens interpolation iff the next character is `{`, `_`, an ASCII
letter, or a non-ASCII Java identifier part (surrogate pairs included).
Otherwise `$` is a string character. Double-quoted GString `$`
(unescaped) always starts interpolation.

**R3** (`TdqStringCharacter` / `TsqStringCharacter`)::
An interior `"` (resp. `'`) is a character when the g4 lookahead holds:

    LA(1) != Q || LA(2) != Q
      || LA(3) == Q && (LA(4) != Q || LA(5) != Q)

where `Q` is the quote. That is the four-/five-quote exception: a run
that looks like a closer is a character plus a closer when a fourth
quote follows. It is not merely "not the start of `"""` / `'''`".

**R4** (`DollarSlashyStringCharacter`)::
Ordered, predicated alternatives:

* `$/$` (escaped closer) only if `LA(-4) != '$'` after the match;
* `$/` (escaped slash) only if `LA(1) != '$'`;
* `/` as a character only if `LA(1) != '$'`;
* `$` as a character only if R2 *fails*.

**R5** (`VAL : 'val' {isValEnabled()}?`)::
If `groovy.val.enabled` is `false` (default `true`), `val` is
`Identifier`, not `VAL`.

**R6** (`NOT_INSTANCEOF`, `NOT_IN`)::
`!instanceof` is one token only if followed by space / tab / CR / LF.
`!in` is one token only if followed by space / tab / CR / LF / `[` /
`(` / `{`. Otherwise they are `NOT` plus `INSTANCEOF` / `IN`
(`!internal` is not `NOT_IN`).

**R7** (`CapitalizedIdentifier` / `Identifier`, `JavaLetter`,
`JavaLetterOrDigit`)::
ASCII is the DFA split `[A-Z]` vs `[a-z$_]`. BMP non-ASCII starts and
continuations require `Character.isJavaIdentifierStart` / `Part` **and
not** `Character.isIdentifierIgnorable`. Supplementary-plane letters
use the decoded code point (GROOVY-12398) and test start/part plus
case only -- they do **not** test identifier-ignorable.

**R8** (`JavaLetterInGString`)::
GString identifiers cannot contain `$`.

**R9** (`isInsideParens` / `ignoreTokenInsideParens`)::
Newline hiding as in <<grammar-lexical>>.

**R10** (`ignoreMultiLineCommentConditionally`)::
Multiline-comment channel as in <<grammar-lexical>>.

**R11** (`SH_COMMENT`)::
`#!` is skipped when `tokenIndex == 0`. Skipped `WS` does not increment
`tokenIndex`; a prior default-channel token (including `NL`) does.
This is not "the first character of the file must be `#`".

=== Parser disambiguation and context gates

**R12** (`isInvalidMethodDeclaration` on `scriptStatement`)::
A script-level `methodDeclaration` is refused when the next two tokens
are `(Identifier | CapitalizedIdentifier | StringLiteral | YIELD)`
immediately followed by `'('`. That input is a call (or `yield(...)`),
parsed through `statement`.

**R13** (`isInvalidLocalVariableDeclaration`)::
A `localVariableDeclaration` is refused when the upcoming tokens look
like a command rather than a typed local. The predicate:

* walks a dotted name (`foo.Bar`) and then inspects the last segment;
* treats the construct as a local if that segment is a primitive, a
  modifier, starts with an uppercase code point, is `@` (unless it is
  an annotated `for` / `while` / `do`), or is followed by `'='` /
  `'<'` / `'['` at the documented `LT` offsets (`string x = 1` is a
  local; `string x` is a command).

Consequence: `String x` and `java.lang.String x` are locals;
`string x` and `java.lang.string x` are commands.

**R14** (`isIdentifierAssign` on `elementValues`)::
`@Foo(a = 1)` is `elementValuePairs` only. A single `elementValue` is
not attempted when `LT(1)` is in FIRST(`elementValuePairName`) and
`LT(2)` is `'='` (GROOVY-12398 / AdaptivePredict).

**R15** (`classBody` `{ $t == 2 }?`)::
Enum bodies may start with `enumConstants`. Other `classBody` values
may not.

**R16** (`methodDeclaration` `{ $ct == 3 }?`)::
`default` annotation element values only when the enclosing type is
`@interface` (`ct == 3`). Script methods use `ct == 9` and do not get
this alternative.

**R17** (`isFollowingArgumentsOrClosure`)::
In `commandExpression`, the optional `argumentList` after `expression`
is absent if that expression is a postfix path whose last
`pathElement` has `t` equal to 2 or 3 (already `arguments` or
`closureOrLambdaExpression`).

**R18** (`pathExpression` `{ LT(2) == DOT }? STATIC`)::
Bare `static` is a path head only when immediately followed by `.`
(e.g. `static.unused = { -> }`).

**R19** (`inSwitchExpressionLevel > 0`)::
`yield expression` is a statement only while parsing
`switchExpression`.

**R20** (`inAsyncClosureLevel > 0`)::
`defer statementExpression` only while parsing the `async`
closure/lambda alternative of `expression`.

**R21** (`AstBuilder.visitExpressionListElement`)::
`'*' expression` (spread) is parsed everywhere
`expressionListElement` occurs; **rejected** in `forInit` /
`forUpdate` (`canSpread == false`). This is conversion, not
recognition.

`<assoc=right>` on `==>`, ternary / elvis, and assignment is CFG
disambiguation of an ambiguous grammar, recorded in the precedence
table, not numbered here.

[[grammar-compilation-unit]]
== Compilation units

The parser start rule is `compilationUnit`. One compilation unit is one
source file: optional package, then a sequence of script statements,
then end of file. Leading `NL` tokens (blank lines, and comments
rewritten to `NL`) are permitted before the package.

[source,ebnf]
----
compilationUnit ::=
    NL* (packageDeclaration sep?)? scriptStatements? EOF

scriptStatements ::=
    scriptStatement (sep scriptStatement)* sep?

scriptStatement ::=
      importDeclaration
    | typeDeclaration
    | methodDeclaration                 /* R12; g4 call is methodDeclaration[3, 9] */
    | statement

packageDeclaration ::=
    annotationsOpt 'package' qualifiedName

importDeclaration ::=
    annotationsOpt 'import'
    (   'module' qualifiedName
      | 'static'? qualifiedName ('.' '*' | 'as' identifier)?
    )

sep ::=
    (NL | ';')+
----

A compilation unit is a *script* in the syntactic sense: it may mix
imports, type declarations, script-level methods, and statements in
one list. Conversion wraps script statements in a generated class;
that wrapping is not syntax. There is no Java-style "one public type
per compilation unit" production. JEP 445 compatible-script *shape* is
conversion, not a second start rule.

=== Package and import

If a package declaration is present it is the first non-`NL`
construct; the CFG already enforces that.

`importDeclaration` has two branches:

* `import module qualifiedName` -- JEP 476-style module import. The g4
  does not admit `import module p.*` or `import module p as x`.
* `import static? qualifiedName` with optional `.*` or
  `as identifier`.

`'module'` is token `MODULE` and is also an alternative of
`identifier`.

Default imports (`java.lang.*`, ...) are inserted later. They are not
productions.

Package names may contain `'def'` `'in'` `'as'` `'trait'`
(`qualifiedNameElement`) for integration with existing Java packages.

=== Script-level methods (R12)

The g4 writes the method alternative as
`{ !SemanticPredicates.isInvalidMethodDeclaration(_input) }?
methodDeclaration[3, 9]`.

R12: if the next two tokens are a name or string (or `yield`)
immediately followed by `'('`, the alternative is not taken.

The parameters `[3, 9]` are not EBNF. `9` records "enclosing type is
script" for conversion. The `default` annotation-element alternative
is gated by R16 and does **not** apply to script methods.

A script method without a body is accepted by the CFG (the body is
optional) and rejected by `AstBuilder`. That check is conversion, not
R12.

=== Newlines between script statements

Adjacent `scriptStatement`s require `sep`: at least one visible
newline or semicolon. Two statements on one line need `';'`. A
trailing `sep` before `EOF` is allowed.

Inside `'('`, `'['`, or `'?['`, `NL` is hidden (R9), so those
newlines do not satisfy `sep`. Inside `'{'` they do. The
try-with-resources list uses `sep` between resources *because*
`try (` is exempt from R9.

[[grammar-types-and-names]]
== Types and names

[source,ebnf]
----
qualifiedName ::=
    qualifiedNameElement ('.' qualifiedNameElement)*

qualifiedNameElement ::=
    identifier | 'def' | 'in' | 'as' | 'trait'

qualifiedNameElements ::=
    (qualifiedNameElement '.')*

qualifiedClassName ::=
    qualifiedNameElements identifier

qualifiedStandardClassName ::=
    qualifiedNameElements className ('.' className)*

className ::=
    CapitalizedIdentifier

identifier ::=
      Identifier
    | CapitalizedIdentifier
    | 'as' | 'async' | 'await' | 'defer' | 'in' | 'module'
    | 'permits' | 'record' | 'sealed' | 'trait' | 'val' | 'var' | 'yield'

keywords ::=
      'abstract' | 'as' | 'assert' | 'async' | 'await' | 'break'
    | 'case' | 'catch' | 'class' | 'const' | 'continue' | 'def'
    | 'default' | 'defer' | 'do' | 'else' | 'enum' | 'extends'
    | 'final' | 'finally' | 'for' | 'goto' | 'if' | 'implements'
    | 'import' | 'in' | 'instanceof' | 'interface' | 'native'
    | 'new' | 'non-sealed' | 'package' | 'permits' | 'record'
    | 'return' | 'sealed' | 'static' | 'strictfp' | 'super'
    | 'switch' | 'synchronized' | 'this' | 'throw' | 'throws'
    | 'transient' | 'trait' | 'threadsafe' | 'try' | 'val' | 'var'
    | 'volatile' | 'while' | 'yield'
    | NullLiteral | BooleanLiteral
    | BuiltInPrimitiveType | 'void'
    | 'public' | 'protected' | 'private'

builtInType ::=
    BuiltInPrimitiveType | 'void'

type ::=
    annotationsOpt
    ( 'void'                           /* parsed; rejected at conversion */
    | primitiveType
    | referenceType
    )
    dim0*

primitiveType ::=
    BuiltInPrimitiveType

referenceType ::=                       /* GROOVY-12319 rare types */
    qualifiedClassName
    (typeArguments ('.' identifier typeArguments?)*)?

standardType ::=                        /* restricted form of type */
    annotationsOpt
    ( primitiveType | standardClassOrInterfaceType )
    dim0*

standardClassOrInterfaceType ::=        /* restricted form of referenceType */
    qualifiedStandardClassName
    (typeArguments ('.' className typeArguments?)*)?

matchingType ::=                        /* instanceof pattern (JEP 394) */
    standardType identifier?

notInstanceofType ::=
    matchingType
  | castParExpression

typeParameters ::=
    '<' NL* typeParameter (',' NL* typeParameter)* NL* '>'

typeParameter ::=
    annotationsOpt className ('extends' NL* typeBound)?

typeBound ::=
    type ('&' NL* type)*

typeList ::=
    type (',' NL* type)*

typeArguments ::=
    '<' NL* typeArgument (',' NL* typeArgument)* NL* '>'

typeArgument ::=
    type
  | annotationsOpt '?' (('extends' | 'super') NL* type)?

typeArgumentsOrDiamond ::=
    '<' '>'
  | typeArguments

nonWildcardTypeArguments ::=
    '<' NL* typeList NL* '>'

dim0 ::=
    annotationsOpt '[' ']'

dim1 ::=
    annotationsOpt '[' expression ']'

intersectionType ::=
    type ('&' NL* type)*

castParExpression ::=
    '(' intersectionType ')'

coercionType ::=
    castParExpression                  /* (T) or (A & B & ...) */
  | type

annotatedQualifiedClassName ::=
    annotationsOpt qualifiedClassName

qualifiedClassNameList ::=
    annotatedQualifiedClassName (',' NL* annotatedQualifiedClassName)*
----

`'module'` is in `identifier` and **not** in `keywords`. Intersection
types appear in **casts and `as`**, not as general types. `void` as a
value type is parsed (`type` has a `'void'` alternative marked error
in the g4) and rejected later.

`instanceof` takes `matchingType` (optional pattern variable).
`!instanceof` takes `notInstanceofType`; conversion rejects
intersection on `!instanceof`.

[[grammar-declarations]]
== Declarations

=== Modifiers

[source,ebnf]
----
typeDeclaration ::=
    classOrInterfaceModifiersOpt classDeclaration

classOrInterfaceModifiersOpt ::=
    (classOrInterfaceModifiers NL*)?

classOrInterfaceModifiers ::=
    classOrInterfaceModifier (NL* classOrInterfaceModifier)*

classOrInterfaceModifier ::=
      annotation
    | 'public' | 'protected' | 'private' | 'static' | 'abstract'
    | 'sealed' | 'non-sealed'
    | 'final'                          /* class only, semantically */
    | 'strictfp'
    | 'default'                        /* interface only, semantically */

modifier ::=
      classOrInterfaceModifier
    | 'native' | 'synchronized' | 'transient' | 'volatile'
    | 'def' | 'val' | 'var'

modifiersOpt ::= (modifiers NL*)?
modifiers    ::= modifier (NL* modifier)*

variableModifier ::=
      annotation
    | 'final' | 'def' | 'val' | 'var'
    | 'public' | 'protected' | 'private' | 'static' | 'abstract' | 'strictfp'

variableModifiersOpt ::= (variableModifiers NL*)?
variableModifiers    ::= variableModifier (NL* variableModifier)*
----

Repeat modifiers, illegal combinations (`sealed` + `non-sealed`,
`sealed` + `final`, `permits` without `sealed`), and "visibility
implies field not property" are conversion / later phases.

=== Type declarations

One production `classDeclaration` with local `t` set from the keyword:

[source,ebnf]
----
classDeclaration ::=
    ( 'class' | 'interface' | 'enum' | '@' 'interface' | 'trait' | 'record' )
    identifier
    (NL* typeParameters)?
    (NL* formalParameters)?            /* record header; illegal for others at conversion */
    (NL* 'extends'    NL* typeList)?
    (NL* 'implements' NL* typeList)?
    (NL* 'permits'    NL* typeList)?
    NL* classBody                      /* R15: enum vs others */
----

[cols="1,1,2", options="header"]
|===
| `t`
| Keyword
| Body

| 0
| `'class'`
| `classBody` without `enumConstants`

| 1
| `'interface'`
| same

| 2
| `'enum'`
| R15: may start with `enumConstants`

| 3
| `'@' 'interface'`
| same as class; methods may have `default` values (R16)

| 4
| `'trait'`
| Groovy-only keyword

| 5
| `'record'`
| header via optional `formalParameters`
|===

`@Sealed` / `@RecordType` / `@Trait` *annotation* styles are
annotations plus AST transforms, not additional keywords.

[source,ebnf]
----
classBody ::=
    '{' NL*
    (
        enumConstants                  /* R15, t == 2 */
        ( (NL* ',')?
        | ((NL* ',')? NL* ';')? NL*
          classBodyDeclaration (sep classBodyDeclaration)*
        )
      | (classBodyDeclaration (sep classBodyDeclaration)*)?
    )
    sep? '}'

enumConstants ::=
    enumConstant (NL* ',' NL* enumConstant)*

enumConstant ::=
    annotationsOpt identifier arguments? anonymousInnerClassDeclaration?

classBodyDeclaration ::=
      ('static' NL*)? block            /* instance / static initializer */
    | memberDeclaration

memberDeclaration ::=
      methodDeclaration
    | fieldDeclaration
    | modifiersOpt (classDeclaration | compactConstructorDeclaration)
----

Nested types are `modifiersOpt classDeclaration`. Anonymous inner
classes use `classBody` with `t == 0` regardless of the ANTLR
parameter on `anonymousInnerClassDeclaration`.

=== Methods, constructors, fields

[source,ebnf]
----
methodDeclaration ::=
    modifiersOpt typeParameters? (returnType NL*)?
    methodName formalParameters
    (   ('default' NL* elementValue)   /* R16: @interface only */
      | NL* 'throws' NL* qualifiedClassNameList (NL* methodBody)?
      | NL* methodBody
    )?

compactConstructorDeclaration ::=
    methodName NL* methodBody          /* no parameter list */

methodName ::=
    identifier | stringLiteral

returnType ::=
    standardType | 'void'

fieldDeclaration ::=
    variableDeclaration

variableDeclaration ::=
      modifiers NL*
      ( type? variableDeclarators
      | typeNamePairs NL* '=' NL* variableInitializer
      )
    | type variableDeclarators

variableDeclarators ::=
    variableDeclarator (',' NL* variableDeclarator)*

variableDeclarator ::=
    variableDeclaratorId (NL* '=' NL* variableInitializer)?

variableDeclaratorId ::=
    identifier

variableInitializer ::=
    enhancedStatementExpression

formalParameters ::=
    '(' formalParameterList? ')'

formalParameterList ::=
    (formalParameter | thisFormalParameter) (',' NL* formalParameter)*

thisFormalParameter ::=
    type 'this'

formalParameter ::=
    variableModifiersOpt type? '...'? variableDeclaratorId
    (NL* '=' NL* expression)?

methodBody ::=
    block
----

There is **no** separate constructor production. A constructor is a
`methodDeclaration` with no `returnType`, name equal to the class
name, and a body -- those checks are `AstBuilder`. Compact
constructors are syntax; "records only, name equals record name" is
conversion.

Properties are **not** a production. The same field production is a
property at conversion when it has no visibility modifier.

Default argument values, optional types, and varargs are syntax.
Duplicate / non-last varargs, `val`/`var` as a return type, and
script abstract methods are conversion.

=== Annotations

[source,ebnf]
----
annotationsOpt ::=
    (annotation (NL* annotation)* NL*)?

annotation ::=
    '@' annotationName (NL* '(' elementValues? ')')?

annotationName ::=
    qualifiedClassName

elementValues ::=
      elementValuePairs
    | elementValue                     /* R14 */

elementValuePairs ::=
    elementValuePair (',' elementValuePair)*

elementValuePair ::=
    elementValuePairName NL* '=' NL* elementValue

elementValuePairName ::=
    identifier | keywords

elementValue ::=
      elementValueArrayInitializer
    | annotation
    | expression

elementValueArrayInitializer ::=
      '[' (elementValue (',' elementValue)* ','?)? ']'
    | '{' (elementValue ',')+ elementValue? '}'   /* at least one comma, vs closure */
----

`elementValue` is a general `expression` (closures as annotation
values are syntax). Inside annotation parentheses, newlines are
already hidden (R9), so R14 can look at `LT(2)`.

[[grammar-statements]]
== Statements

[source,ebnf]
----
block ::=
    '{' sep? blockStatementsOpt '}'

blockStatementsOpt ::=
    blockStatements?

blockStatements ::=
    blockStatement (sep blockStatement)* sep?

blockStatement ::=
    statement

statement ::=
      block
    | conditionalStatement
    | loopStatement
    | tryCatchStatement
    | 'synchronized' expressionInPar NL* block
    | 'return' expression?
    | 'throw' expression
    | breakStatement
    | continueStatement
    | yieldStatement                   /* R19 */
    | 'yield' 'return' NL* expression  /* always; generator */
    | 'defer' NL* statementExpression  /* R20 */
    | identifier ':' NL* statement
    | assertStatement
    | localVariableDeclaration         /* R13 */
    | statementExpression
    | ';'

conditionalStatement ::=
    ifElseStatement | switchStatement

ifElseStatement ::=
    'if' expressionInPar NL* statement
    ((NL* | sep) 'else' NL* statement)?

switchStatement ::=
    'switch' expressionInPar NL*
    '{' NL* (switchBlockStatementGroup+ NL*)? '}'

switchBlockStatementGroup ::=
    switchLabel (NL* switchLabel)* NL* blockStatements

switchLabel ::=
      'case' expression ':'
    | 'default' ':'

loopStatement ::=
      annotationsOpt 'for' 'await'? '(' forControl ')' NL* statement
    | annotationsOpt 'while' expressionInPar NL* statement
    | annotationsOpt 'do' NL* statement NL* 'while' expressionInPar

forControl ::=
    enhancedForControl | originalForControl

enhancedForControl ::=
    (indexVariable ',')? variableModifiersOpt type? identifier
    (':' | 'in') expression

indexVariable ::=
    (BuiltInPrimitiveType | 'def' | 'val' | 'var')? identifier

originalForControl ::=
    forInit? ';' expression? ';' forUpdate?

forInit ::=
    localVariableDeclaration | expressionList   /* canSpread false: R21 */

forUpdate ::=
    expressionList                              /* canSpread false: R21 */

continueStatement ::= 'continue' identifier?
breakStatement    ::= 'break'    identifier?
yieldStatement    ::= 'yield' expression

tryCatchStatement ::=
    'try' resources? NL* block
    (NL* catchClause)*
    (NL* finallyBlock)?

resources ::=
    '(' NL* resourceList sep? ')'

resourceList ::=
    resource (sep resource)*

resource ::=
    localVariableDeclaration | expression

catchClause ::=
    'catch' '(' variableModifiersOpt catchType? identifier ')' NL* block

catchType ::=
    qualifiedClassName ('|' qualifiedClassName)*

finallyBlock ::=
    'finally' NL* block

assertStatement ::=
    'assert' expression (NL* (':' | ',') NL* expression)?

localVariableDeclaration ::=
    variableDeclaration                /* R13 */

typeNamePairs ::=
    '(' ( typeNamePair (',' typeNamePair)*
        | keyedPair    (',' keyedPair)*
        ) ')'

typeNamePair ::=
    ('def' | 'val' | 'var' | type)? '*'? variableDeclaratorId

keyedPair ::=
    identifier ':' ('def' | 'val' | 'var' | type)? variableDeclaratorId

variableNames ::=
    '(' variableDeclaratorId (',' variableDeclaratorId)+ ')'
----

Switch **statement** labels are `case expression ':'` / `default ':'`
only -- no arrow, no `expressionList`, no `yield`. Switch
**expressions** are a different nonterminal
(<<grammar-expressions>>).

`yield expression` is gated by R19. `yield return expression` is a
**separate**, always-available alternative and must not be folded into
`yieldStatement`.

`defer` is gated by R20. `for await` is syntax (`'await'?` on `for`).
Loop annotations (`annotationsOpt` on `for`/`while`/`do`) are syntax;
R13 keeps `@Ann for (` as a loop.

`assert` allows `:` **or** `,` before the message. `try { }` with no
catch, finally, or resources is parsed and rejected later. TWR
resources are separated by `sep` (newline or `;`), not only `;`.

`variableNames` requires **at least two** identifiers. `(a) = ...` is
ordinary assignment; nested `((a))` is rejected at conversion.

[[grammar-expressions]]
== Expressions

Two facts must not be simplified away:

* The CFG of operators is the left-recursive rule `expression`. ANTLR
  binds *earlier alternatives tighter*.
* Every *statement* expression is a `commandExpression`. Command
  syntax is not a side dialect.

=== Compact form

The alternatives below are those of `expression` in `GroovyParser.g4`,
in the same order. Shift and assignment operators are inlined (there
are no `LSHIFT` / `RSHIFT` / `URSHIFT` lexer tokens).

[source,ebnf]
----
expression ::=
      castParExpression castOperandExpression          /* cast, tightest */
    | 'async' NL* closureOrLambdaExpression            /* R20 enters */
    | 'await' NL*
          ( '(' expression (',' NL* expression)* ')'
          | expression (',' NL* expression)*
          )
    | postfixExpression
    | switchExpression                                 /* R19 enters */
    | ('~' | '!') NL* expression
    | expression '**' NL* expression                   /* left-assoc */
    | ('++' | '--' | '+' | '-') expression
    | expression NL* ('*' | DIV | '%') NL* expression
    | expression ('+' | '-') NL* expression            /* no NL before +/− */
    | expression NL*
          ('<' '<' | '>' '>' '>' | '>' '>'
          | '..' | '<..' | '..<' | '<..<')
          NL* expression
    | expression NL* 'instanceof' NL* matchingType
    | expression NL* '!instanceof' NL* notInstanceofType
    | expression NL* 'as' NL* coercionType
    | expression NL* ('<=' | '>=' | '>' | '<' | 'in' | '!in')
                 NL* expression
    | expression NL*
          ('===' | '!==' | '==' | '!=' | '<=>') NL* expression
    | expression NL* ('=~' | '==~') NL* expression
    | expression NL* '&'  NL* expression
    | expression NL* '^'  NL* expression
    | expression NL* '|'  NL* expression
    | expression NL* '&&' NL* expression
    | expression NL* '||' NL* expression
    | expression NL* '==>' NL* expression              /* right-assoc */
    | expression NL*
          ( '?' NL* expression NL* ':' NL* | '?:' NL* )
          expression                                   /* right-assoc */
    | variableNames NL* '=' NL* statementExpression    /* prefix; right-assoc */
    | expression NL*
          ('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^='
          | '>>=' | '>>>=' | '<<=' | '%=' | '**=' | '?=')
          NL* enhancedStatementExpression              /* right-assoc */

castOperandExpression ::=              /* restricted form of expression */
      castParExpression castOperandExpression
    | postfixExpression
    | ('~' | '!') NL* castOperandExpression
    | ('++' | '--' | '+' | '-') castOperandExpression

postfixExpression ::=
    pathExpression ('++' | '--')?

statementExpression ::=
    commandExpression

enhancedExpression ::=
    expression | standardLambdaExpression

enhancedStatementExpression ::=
    statementExpression | standardLambdaExpression

expressionInPar ::=
    '(' enhancedStatementExpression ')'

parExpression ::=
    expressionInPar

expressionList ::=
    expressionListElement (',' NL* expressionListElement)*

expressionListElement ::=
    '*'? expression                    /* R21: spread rejected in forInit/forUpdate */
----

`DIV` is the division token, spelling `'/'`. It is not written `'/'`
here because that character also opens slashy strings (R1).

`castOperandExpression` exists so `(int) a + b` is `((int) a) + b` and
`(int) ++x` is a cast of a prefix.

`await` takes a full `expression` (or a parenthesised list). So
`await a + b` is `await (a + b)`.

=== Precedence and associativity

Derived from the alternative **order** of `expression` as implemented
by the generated `expression(int)` method, not copied from the tutorial
table in `core-operators.adoc`. Rows are tightest first. The column
"Level (g4 comment)" repeats the comments in the g4; the *(atom)* row
is tighter than that numbering's "level 1".

Because `instanceof`, `!instanceof`, `as`, and comparisons are
**separate** alternatives, ANTLR assigns them distinct numeric
precedences (tighter in that order). The g4 comments still call the
group "level 7"; the table keeps that grouping and notes the split.

[cols="1,2,2,1", options="header"]
|===
| Level (g4 comment)
| Operators / forms
| Alternative
| Assoc.

| (atom)
| `(T) e`, `async { }`, `await e`, path/postfix, `switch (e) { }`
| `#castExprAlt` `#asyncClosureExprAlt` `#awaitExprAlt` `#postfixExprAlt` `#switchExprAlt`
| n/a

| 1
| `~` `!`
| `#unaryNotExprAlt`
| prefix

| 2
| `**`
| `#powerExprAlt`
| **left** (not marked `<assoc=right>`)

| 3
| prefix `++` `--` `+` `-`
| `#unaryAddExprAlt`
| prefix

| 4
| `*` `/` `%`
| `#multiplicativeExprAlt`
| left

| 5
| `+` `-`
| `#additiveExprAlt`
| left

| 6
| `<<` `>>` `>>>` `..` `..<` `<..<` `<..`
| `#shiftExprAlt`
| left

| 7
| `instanceof`, then `!instanceof`, then `as`, then `< \<= > >= in !in`
| `#relationalExprAlt` (four alts; earlier is tighter)
| left / type RHS

| 8
| `==` `!=` `<=>` `===` `!==`
| `#equalityExprAlt`
| left

| 8.5
| `=~` `==~`
| `#regexExprAlt`
| left

| 9
| `&`
| `#andExprAlt`
| left

| 10
| `^`
| `#exclusiveOrExprAlt`
| left

| 11
| `\|`
| `#inclusiveOrExprAlt`
| left

| 12
| `&&`
| `#logicalAndExprAlt`
| left

| 13
| `\|\|`
| `#logicalOrExprAlt`
| left

| 13.5
| `==>`
| `#implicationExprAlt`
| **right**

| 14
| `? :` `?:`
| `#conditionalExprAlt`
| **right**

| 15
| assignment operators
| `#assignmentExprAlt` (`_prec(1)`; RHS is `enhancedStatementExpression`)
| **right**

| (prefix)
| `(a, b) = ...`
| `#multipleAssignmentExprAlt` (not left-recursive; parsed as a prefix
  alternative of `expression`, like cast)
| n/a
|===

Notes the tutorial table does not make:

* `**` sits *between* `!` and unary minus: `!a ** b` is `(!a) ** b`;
  `-a ** b` is `-(a ** b)` (Python-style). The g4 comments call these
  levels 1, 2, 3.
* `**` is **left**-associative in this grammar.
* Path operators `.` `?.` `??.` `*.` `.&` `::` `.@` `()` `{}` `[]`
  `?[]` live in `pathElement`, inside `postfixExpression`, tighter
  than the table above.
* Newline **before** `+`, `-`, or `**` is *not* part of those
  operators (`NL*` is only on the right). At script top level that
  newline is `sep` and the next line starts a new `statement`.
  Newline before `*`, `/`, comparison, `=`, ... *is* allowed when the
  `NL` is visible.

=== Path expressions

[source,ebnf]
----
pathExpression ::=
    ( primary
    | 'static'                         /* R18: only when next token is '.' */
    )
    pathElement*

pathElement ::=
      NL*
      ( '.' NL*
            ( 'new' nonWildcardTypeArguments? creator
            | ('@' | nonWildcardTypeArguments)? namePart
            )
        | ( '*.' | '?.' | '??.' ) NL* ('@' | nonWildcardTypeArguments)? namePart
        | '.&' NL* namePart
        | '::' NL* nonWildcardTypeArguments? namePart
        | closureOrLambdaExpression
      )
    | arguments
    | indexPropertyArgs
    | namedPropertyArgs

namePart ::=
    identifier | stringLiteral | dynamicMemberName | keywords

dynamicMemberName ::=
    parExpression | gstring

indexPropertyArgs ::=
    ('?[' | '[') expressionList? ']'

namedPropertyArgs ::=
    ('?[' | '[') (namedPropertyArgList | ':') ']'
----

`pathElement` `t` codes (CST tags for R17 / conversion, not EBNF
parameters): 1 namePart, 2 arguments, 3 closure/lambda, 4 index, 5
named index, 6 `outer.new Inner(...)`.

`arguments` / index / named index do **not** have a leading `NL*` in
this production. A newline before `(` at script level is `sep`, not a
call. Inside grouping, that newline is hidden (R9).

The unimplemented proposal `a.\{foo}` as inline `with` is a comment in
the g4, not a production.

=== Primaries, lists, maps, creation

[source,ebnf]
----
primary ::=
      identifier typeArguments?
    | literal
    | gstring
    | 'new' NL* nonWildcardTypeArguments? creator
    | nonWildcardTypeArguments? 'this'
    | nonWildcardTypeArguments? 'super'
    | parExpression
    | closureOrLambdaExpression
    | list
    | map
    | builtInType

literal ::=
    IntegerLiteral | FloatingPointLiteral | stringLiteral
  | BooleanLiteral | NullLiteral

stringLiteral ::=
    StringLiteral

list ::=
    '[' expressionList? ','? ']'

map ::=
    '[' (mapEntryList ','? | ':') ']'

mapEntryList ::=
    mapEntry (',' mapEntry)*

mapEntry ::=
      mapEntryLabel ':' NL* enhancedExpression
    | '*' ':' NL* enhancedExpression

mapEntryLabel ::=
    keywords | primary

creator ::=
    createdName
    (   NL* arguments anonymousInnerClassDeclaration?
      | dim0+ NL* arrayInitializer
      | dim1+ dim0*
    )

createdName ::=
    annotationsOpt
    ( primitiveType
    | qualifiedClassName
      (typeArgumentsOrDiamond ('.' identifier typeArgumentsOrDiamond?)*)?
    )

arrayInitializer ::=
    '{' NL*
    ( (arrayInitializer | variableInitializer) NL*
      (',' NL* (arrayInitializer | variableInitializer) NL*)*
    )?
    ','? NL* '}'

anonymousInnerClassDeclaration ::=
    classBody

arguments ::=
    '(' enhancedArgumentListInPar? ','? ')'

enhancedArgumentListInPar ::=
    enhancedArgumentListElement
    (',' NL* enhancedArgumentListElement)*

enhancedArgumentListElement ::=
      expressionListElement
    | standardLambdaExpression
    | namedPropertyArg

argumentList ::=                        /* command / chain args; restricted form */
    firstArgumentListElement
    (',' NL* argumentListElement)*

firstArgumentListElement ::=
    expressionListElement | namedArg

argumentListElement ::=
    expressionListElement | namedPropertyArg

namedArg ::=
      namedArgLabel ':' NL* enhancedExpression
    | '*' ':' NL* enhancedExpression

namedPropertyArg ::=
      namedPropertyArgLabel ':' NL* enhancedExpression
    | '*' ':' NL* enhancedExpression

namedArgLabel ::=
    keywords | namedArgPrimary

namedPropertyArgLabel ::=
    keywords | namedPropertyArgPrimary

namedPropertyArgList ::=
    namedPropertyArg (',' namedPropertyArg)*

namedArgPrimary ::=
    identifier | literal | gstring

namedPropertyArgPrimary ::=
    identifier | literal | gstring | parExpression | list | map
----

Trailing commas are allowed in lists, maps, and argument lists.
`[:]` is the empty map. `*` `:` is map spread.

=== Command expressions (R17)

[source,ebnf]
----
commandExpression ::=
    expression
    argumentList?                      /* R17 */
    commandArgument*

commandArgument ::=
    commandPrimary (pathElement+ | argumentList)?

commandPrimary ::=                     /* restricted primary */
    identifier | literal | gstring
----

Every statement expression is a `commandExpression`: an `expression`
followed by an optional `argumentList` (R17) and zero or more
`commandArgument`s. A bare `foo` is therefore a `commandExpression`
with both tails empty. Parentheses around a call may be omitted when
R17 allows an `argumentList` (the callee is not already a `(...)` or
`{...}` path element). Further words are a *command chain*:

* `a b c()` -> `a(b).c()`
* `a b c()()` -> `a(b).c().call()`
* `a b c[x]` -> `a(b).c[x]`
* `a b c { x }` -> `a(b).c({ x })`

R17: `foo(1) bar` does not treat `bar` as a second positional argument
of `foo`; `foo 1 bar` may.

`commandPrimary` cannot be `new`, `this`, a parenthesised expression,
a list, a map, or a closure. Those remain ordinary `expression` heads.

Parenthesised `arguments` may contain `standardLambdaExpression`;
command `argumentList` may not (only `expressionListElement` /
`namedArg` on the first element).

=== Closures and lambdas

[source,ebnf]
----
closure ::=
    '{' (NL* (formalParameterList NL*)? '->')? sep? blockStatementsOpt '}'

lambdaExpression ::=                   /* Groovy lambda: parentheses required */
    lambdaParameters NL* '->' NL* lambdaBody

lambdaParameters ::=
    formalParameters                   /* single id without () is NOT here */

standardLambdaExpression ::=
    standardLambdaParameters NL* '->' NL* lambdaBody

standardLambdaParameters ::=
    formalParameters | variableDeclaratorId

lambdaBody ::=
    block | statementExpression

closureOrLambdaExpression ::=
    closure | lambdaExpression
----

`{ a -> a * 2 }` is a **closure**. The g4 comments out a
`variableDeclaratorId` alternative on `lambdaParameters` so that form
is not stolen from closures (GROOVY-8991). Java-style
`(params) -> body` and `x -> body` are `standardLambdaExpression`,
used in parenthesised argument lists and as
`enhancedStatementExpression`.

=== Switch expressions

[source,ebnf]
----
switchExpression ::=
    'switch' expressionInPar NL*
    '{' NL* switchBlockStatementExpressionGroup* NL* '}'

switchBlockStatementExpressionGroup ::=
    (switchExpressionLabel NL*)+ blockStatements

switchExpressionLabel ::=
    ('case' expressionList | 'default') ('->' | ':')
----

While this production is active, R19 allows `yield expression`.
`return` / `break` / `continue` inside a switch expression are
conversion errors.

Which production matches is a matter of *context and labels*.
`switchStatement` (under `conditionalStatement`) admits only
`case expression ':'` / `default ':'`. Arrow labels exist only on
`switchExpression`. An arrow `switch` in statement position is
therefore `statementExpression` -> `switchExpression`, not
`switchStatement`.

[[grammar-gstring-parser]]
== GString in the parser

Parser `gstring` does not know the quote style. Interpolation is
`gstringPath` or `closure` only -- not an arbitrary `expression`
nonterminal. `gstringPath` cannot include a call: `"$foo.bar()"` is
a path `foo.bar` followed by the characters `()`; `"$\{foo.bar()}"`
is a closure. Conversion may unwrap a no-arrow single-expression
closure.

[[grammar-parameter-bijection]]
== Parameterised-rule bijection

[cols="1,1,1,2", options="header"]
|===
| g4 rule
| Parameter
| Used in recognition?
| Published form

| `classDeclaration`
| locals `t` 0..5
| sets `t` from keyword
| one production; keyword choice is syntax

| `classBody[t]`
| `t == 2` gates `enumConstants`
| **yes** (R15)
| one production with R15

| `classBodyDeclaration[t]` `memberDeclaration[t]`
| passed through
| only to `methodDeclaration[0, t]`
| one production; `t` is AST/context

| `methodDeclaration[t, ct]`
| `ct == 3` gates `default`
| **`ct` yes (R16); `t` no**
| one production with R16. Script call is `[3, 9]`

| `returnType[ct]`
| unused in the production
| no
| one production; parameter dropped

| `variableDeclaration[t]`
| unused (0 local / 1 field is `AstBuilder`)
| no
| one production

| `creator[t]` `anonymousInnerClassDeclaration[t]`
| unused in the production
| no
| one production

| `expressionList[canSpread]` `expressionListElement[canSpread]`
| `MUL?` always parsed
| conversion (R21)
| `'*'? expression`

| `pathExpression` / `pathElement` `returns [int t]`
| CST tag
| R17 reads `t`
| not an EBNF parameter
|===

[[grammar-basecontext]]
== Restricted forms (`baseContext`)

ANTLR `options { baseContext = X; }` shares a generated context class.
Each is still a distinct production and is listed above:

[cols="1,1,2", options="header"]
|===
| Rule
| Base
| Drops / tightens

| `standardType`
| `type`
| no `'void'` alternative; uses `standardClassOrInterfaceType`

| `standardClassOrInterfaceType`
| `referenceType`
| `className` (`CapitalizedIdentifier`) instead of `identifier`

| `lambdaExpression`
| `standardLambdaExpression`
| parameters must be `formalParameters`

| `lambdaParameters`
| `standardLambdaParameters`
| no single `variableDeclaratorId`

| `castOperandExpression`
| `expression`
| only cast, postfix, unary not, unary add/sub

| `commandPrimary`
| `primary`
| `identifier` `literal` `gstring` only

| `namedArgPrimary`
| `primary`
| identifier / literal / gstring

| `namedPropertyArgPrimary`
| `primary`
| plus parExpression / list / map

| `namedPropertyArgList`
| `mapEntryList`
| `namedPropertyArg` elements

| `namedPropertyArg` `namedArg`
| `mapEntry`
| corresponding labels

| `namedPropertyArgLabel` `namedArgLabel`
| `mapEntryLabel`
| corresponding primaries

| `argumentList`
| `enhancedArgumentListInPar`
| no `standardLambdaExpression`; first element may be `namedArg`

| `firstArgumentListElement` `argumentListElement`
| `enhancedArgumentListElement`
| as above
|===

[[grammar-overapprox]]
== Syntactic over-approximation

The CFG accepts programs that conversion or later phases reject.
Representative cases (not an exhaustive semantic-analysis list):

* `'void'` as a value type; `void[]`.
* `formalParameters` on non-records; `extends` / `implements` /
  `permits` / `typeParameters` on kinds that cannot have them;
  `var` / `val` as a type name.
* Methods without bodies in classes; abstract methods with bodies;
  annotation methods with a body or `void`; script abstract methods.
* Compact constructor outside a record / name mismatch.
* `this(...)` / `super(...)` not the first constructor statement
  (grammar allows them anywhere a path can appear).
* `try { }` with no catch, finally, or resources.
* Switch: more than one `default`; switch **expression**
  `return` / `break` / `continue`.
* Nested `((a)) = ...`; assignment LHS not variable / property / index.
* `!instanceof (A & B)`; non-reifiable `instanceof`.
* Spread `*` in `forInit` / `forUpdate` (R21). Spread is *recognised*
  wherever `expressionListElement` occurs, including
  `switchExpressionLabel` (`case *x ->`); R21 conversion-checks only
  for-init/update.
* `for await` is not gated by `inAsyncClosureLevel` (only `defer` is
  R20).
* Command chains inside `arrayInitializer`.
* Primitive type used as a method name `int()`.

[[grammar-invalid]]
== Invalid input and diagnostics

These are **not** language productions:

* Parser error alternatives for missing `)` / `]` / `}` -- removed
  (GROOVY-9588). `MissingDelimiterDiagnostic` may relocate the caret
  after recognition has already failed.
* `UNEXPECTED_CHAR` -- unexpected character; an unexpected quote is
  reported as an unclosed string unless a scan-ahead finds an illegal
  escape in an otherwise closed literal.
* Invalid octal (`'0' [0-9]+` error alternative).
* Number ending with `_`.
* Unclosed `/*` (`requireUnclosedComment` at the opener).
* Shebang when `tokenIndex != 0` (R11).
* `GroovyLangLexer.nextToken`: EOF in `GSTRING_TYPE_SELECTOR_MODE`
  (`Illegal string body character after dollar sign`).
* `errorIgnored` IDE tokenisation.

[[grammar-excluded]]
== Intentionally excluded

Not syntax (not in the g4 as productions of the language):

* AST transforms and their annotations as *language forms*
  (`@CompileStatic`, `@TypeChecked`, `@Field`, `@Sealed` as the
  *alternative* to the `sealed` keyword, ...).
* Groovydoc tag semantics (lexing of `/**` is in; tags are not).
* Type checking, Groovy Truth, operator overloading, optional
  `return` of the last expression.
* Default imports.
* Runtime GString evaluation and `hashCode` coercion.
* Implicit closure parameter `it`.
* JEP 445 script classification.
* Trait *implementation* (the `trait` keyword is syntax; mixin
  semantics are a transform).
* Java `module-info` compilation units; Java text blocks as a
  distinct form (Groovy `"""` is triple-quoted String/GString);
  Java 21+ switch type / record / pattern labels and `when` guards
  (Groovy `case` is `expression` / `expressionList`).

[[grammar-index]]
== Production index

Every named parser rule in `GroovyParser.g4` appears in this chapter.
There is no `nls` rule. Lexer modes are listed under
<<grammar-gstring-lexical>>. Parser-visible tokens and fragments are
in <<grammar-vocabulary>> and <<grammar-lexical>>; rewritten lexer
rules follow this index.

* <<grammar-compilation-unit,Compilation units>>::
  `compilationUnit`, `scriptStatements`, `scriptStatement`,
  `packageDeclaration`, `importDeclaration`, `sep`
* <<grammar-types-and-names,Types and names>>::
  `qualifiedName`, `qualifiedNameElement`, `qualifiedNameElements`,
  `qualifiedClassName`, `qualifiedStandardClassName`, `className`,
  `identifier`, `keywords`, `builtInType`, `type`, `primitiveType`,
  `referenceType`, `standardType`, `standardClassOrInterfaceType`,
  `matchingType`, `notInstanceofType`, `typeParameters`,
  `typeParameter`, `typeBound`, `typeList`, `typeArguments`,
  `typeArgument`, `typeArgumentsOrDiamond`,
  `nonWildcardTypeArguments`, `dim0`, `dim1`, `intersectionType`,
  `castParExpression`, `coercionType`,
  `annotatedQualifiedClassName`, `qualifiedClassNameList`
* <<grammar-declarations,Declarations>>::
  `typeDeclaration`, `modifier`, `modifiersOpt`, `modifiers`,
  `classOrInterfaceModifiersOpt`, `classOrInterfaceModifiers`,
  `classOrInterfaceModifier`, `variableModifier`,
  `variableModifiersOpt`, `variableModifiers`, `classDeclaration`,
  `classBody`, `enumConstants`, `enumConstant`,
  `classBodyDeclaration`, `memberDeclaration`, `methodDeclaration`,
  `compactConstructorDeclaration`, `methodName`, `returnType`,
  `fieldDeclaration`, `variableDeclarators`, `variableDeclarator`,
  `variableDeclaratorId`, `variableInitializer`, `formalParameters`,
  `formalParameterList`, `thisFormalParameter`, `formalParameter`,
  `methodBody`, `annotationsOpt`, `annotation`, `elementValues`,
  `annotationName`, `elementValuePairs`, `elementValuePair`,
  `elementValuePairName`, `elementValue`,
  `elementValueArrayInitializer`
* <<grammar-statements,Statements>>::
  `block`, `blockStatementsOpt`, `blockStatements`, `blockStatement`,
  `statement`, `conditionalStatement`, `ifElseStatement`,
  `switchStatement`, `switchBlockStatementGroup`, `switchLabel`,
  `loopStatement`, `forControl`, `enhancedForControl`,
  `indexVariable`, `originalForControl`, `forInit`, `forUpdate`,
  `continueStatement`, `breakStatement`, `yieldStatement`,
  `tryCatchStatement`, `resources`, `resourceList`, `resource`,
  `catchClause`, `catchType`, `finallyBlock`, `assertStatement`,
  `localVariableDeclaration`, `variableDeclaration`, `typeNamePairs`,
  `typeNamePair`, `keyedPair`, `variableNames`
* <<grammar-expressions,Expressions>>::
  `expression`, `castOperandExpression`, `postfixExpression`,
  `statementExpression`, `enhancedExpression`,
  `enhancedStatementExpression`, `expressionInPar`, `parExpression`,
  `expressionList`, `expressionListElement`, `pathExpression`,
  `pathElement`, `namePart`, `dynamicMemberName`,
  `indexPropertyArgs`, `namedPropertyArgs`, `primary`, `literal`,
  `stringLiteral`, `gstring`, `gstringValue`, `gstringPath`, `list`,
  `map`, `mapEntryList`, `mapEntry`, `mapEntryLabel`, `creator`,
  `createdName`, `arrayInitializer`,
  `anonymousInnerClassDeclaration`, `arguments`,
  `enhancedArgumentListInPar`, `enhancedArgumentListElement`,
  `argumentList`, `firstArgumentListElement`, `argumentListElement`,
  `namedArg`, `namedPropertyArg`, `namedArgLabel`,
  `namedPropertyArgLabel`, `namedPropertyArgList`, `namedArgPrimary`,
  `namedPropertyArgPrimary`, `commandExpression`, `commandArgument`,
  `commandPrimary`, `closure`, `lambdaExpression`,
  `lambdaParameters`, `standardLambdaExpression`,
  `standardLambdaParameters`, `lambdaBody`,
  `closureOrLambdaExpression`, `switchExpression`,
  `switchBlockStatementExpressionGroup`, `switchExpressionLabel`

A unique-spelling keyword or operator `'foo'` is token `FOO`, except:
`non-sealed` is `NON_SEALED`; the eight primitives are one token
`BuiltInPrimitiveType`; `true`/`false` are `BooleanLiteral`; `null`
is `NullLiteral`; `/` as an operator is `DIV`.

Lexer token names in `GroovyLexer.g4` (parser-visible, rewritten, skip,
and diagnostic). This list is the coverage checklist; spellings and
roles are in <<grammar-vocabulary>> and <<grammar-lexical>>.

`AS`, `DEF`, `IN`, `TRAIT`, `THREADSAFE`, `ASYNC`, `AWAIT`, `DEFER`,
`BuiltInPrimitiveType`, `ABSTRACT`, `ASSERT`, `BREAK`, `CASE`, `CATCH`,
`CLASS`, `CONST`, `CONTINUE`, `DEFAULT`, `DO`, `ELSE`, `ENUM`,
`EXTENDS`, `FINAL`, `FINALLY`, `FOR`, `IF`, `GOTO`, `IMPLEMENTS`,
`IMPORT`, `INSTANCEOF`, `INTERFACE`, `MODULE`, `NATIVE`, `NEW`,
`NON_SEALED`, `PACKAGE`, `PERMITS`, `PRIVATE`, `PROTECTED`, `PUBLIC`,
`RECORD`, `RETURN`, `SEALED`, `STATIC`, `STRICTFP`, `SUPER`, `SWITCH`,
`SYNCHRONIZED`, `THIS`, `THROW`, `THROWS`, `TRANSIENT`, `TRY`, `VAL`,
`VAR`, `VOID`, `VOLATILE`, `WHILE`, `YIELD`, `IntegerLiteral`,
`FloatingPointLiteral`, `BooleanLiteral`, `NullLiteral`,
`StringLiteral`, `GStringBegin`, `GStringPart`, `GStringEnd`,
`GStringPathPart`, `TdqGStringBegin`, `TdqGStringPart`, `TdqGStringEnd`,
`TdqGStringCharacter`, `SlashyGStringBegin`, `SlashyGStringPart`,
`SlashyGStringEnd`, `SlashyGStringCharacter`, `DollarSlashyGStringBegin`,
`DollarSlashyGStringPart`, `DollarSlashyGStringEnd`,
`DollarSlashyGStringCharacter`, `GStringCharacter`, `GStringLBrace`,
`GStringIdentifier`, `RollBackOne`, `RANGE_INCLUSIVE`,
`RANGE_EXCLUSIVE_LEFT`, `RANGE_EXCLUSIVE_RIGHT`, `RANGE_EXCLUSIVE_FULL`,
`SPREAD_DOT`, `SAFE_DOT`, `SAFE_INDEX`, `SAFE_CHAIN_DOT`, `ELVIS`,
`METHOD_POINTER`, `METHOD_REFERENCE`, `REGEX_FIND`, `REGEX_MATCH`,
`POWER`, `POWER_ASSIGN`, `SPACESHIP`, `IDENTICAL`, `IMPLIES`,
`NOT_IDENTICAL`, `ARROW`, `NOT_INSTANCEOF`, `NOT_IN`, `LPAREN`,
`RPAREN`, `LBRACE`, `RBRACE`, `LBRACK`, `RBRACK`, `SEMI`, `COMMA`,
`DOT`, `ASSIGN`, `GT`, `LT`, `NOT`, `BITNOT`, `QUESTION`, `COLON`,
`EQUAL`, `LE`, `GE`, `NOTEQUAL`, `AND`, `OR`, `INC`, `DEC`, `ADD`,
`SUB`, `MUL`, `DIV`, `BITAND`, `BITOR`, `XOR`, `MOD`, `ADD_ASSIGN`,
`SUB_ASSIGN`, `MUL_ASSIGN`, `DIV_ASSIGN`, `AND_ASSIGN`, `OR_ASSIGN`,
`XOR_ASSIGN`, `MOD_ASSIGN`, `LSHIFT_ASSIGN`, `RSHIFT_ASSIGN`,
`URSHIFT_ASSIGN`, `ELVIS_ASSIGN`, `CapitalizedIdentifier`, `Identifier`,
`AT`, `ELLIPSIS`, `WS`, `NL`, `ML_COMMENT`, `SL_COMMENT`, `SH_COMMENT`,
`UNEXPECTED_CHAR`.

Lexer rules that are rewritten before the parser sees them:

== Rewritten and mode-local lexer rules (not parser terminals)

These names exist in `GroovyLexer.g4` and are rewritten or accumulated;
the parser never sees the original name.

[cols="1,2", options="header"]
|===
| Lexer rule
| Fate

| `TdqGStringBegin` `SlashyGStringBegin` `DollarSlashyGStringBegin`
| `-> type(GStringBegin)` and `pushMode` of the matching body mode plus
  `GSTRING_TYPE_SELECTOR_MODE`

| `TdqGStringEnd` `SlashyGStringEnd` `DollarSlashyGStringEnd`
| `-> type(GStringEnd)`, `popMode`

| `TdqGStringPart` `SlashyGStringPart` `DollarSlashyGStringPart`
| `-> type(GStringPart)`, `pushMode(GSTRING_TYPE_SELECTOR_MODE)`

| `GStringCharacter` `TdqGStringCharacter` `SlashyGStringCharacter` `DollarSlashyGStringCharacter`
| `-> more` (glued into the following `GStringPart` / `GStringEnd`)

| `GStringLBrace`
| `enterParen()`; `-> type(LBRACE)`; `popMode`; `pushMode(DEFAULT_MODE)`

| `GStringIdentifier`
| `-> type(Identifier)`; `popMode`; `pushMode(GSTRING_PATH_MODE)`

| `RollBackOne`
| `popMode`. Usually `HIDDEN` *and* `rollbackOneChar()`. At EOF after
  `"` or `/`, `type(GStringEnd)` and **no** rollback.
|===

== Lexer fragments

Every fragment used by a token:

`DqStringCharacter`, `SqStringCharacter`, `TdqStringCharacter`,
`TsqStringCharacter`, `SlashyStringCharacter`,
`DollarSlashyStringCharacter`, `BOOLEAN`, `BYTE`, `CHAR`, `DOUBLE`,
`FLOAT`, `INT`, `LONG`, `SHORT`, `DecimalIntegerLiteral`,
`HexIntegerLiteral`, `OctalIntegerLiteral`, `BinaryIntegerLiteral`,
`IntegerTypeSuffix`, `DecimalNumeral`, `Digits`, `Underscores`,
`Underscore`, `HexNumeral`, `HexDigits`, `HexDigit`, `OctalNumeral`,
`OctalDigits`, `BinaryNumeral`, `BinaryDigits`,
`DecimalFloatingPointLiteral`, `ExponentPart`, `FloatTypeSuffix`,
`HexadecimalFloatingPointLiteral`, `HexSignificand`, `BinaryExponent`,
`EscapeSequence`, `OctalEscape`, `UnicodeEscape`, `DollarEscape`,
`LineEscape`, `LineTerminator`, `SlashEscape`, `Backslash`, `Slash`,
`Dollar`, `GStringQuotationMark`, `SqStringQuotationMark`,
`TdqStringQuotationMark`, `TsqStringQuotationMark`,
`DollarSlashyGStringQuotationMarkBegin`,
`DollarSlashyGStringQuotationMarkEnd`, `DollarSlashEscape`,
`DollarDollarEscape`, `DollarSlashDollarEscape`, `IdentifierInGString`,
`JavaLetter`, `JavaLetterInGString`, `JavaLetterOrDigit`,
`JavaLetterOrDigitInGString`, `ShCommand`.

The fragments used by tokens are defined in <<grammar-lexical>>
(`JavaLetter`, `Digits`, `HexDigits`, `OctalEscape`, `UnicodeEscape`,
`ShCommand`, string-character fragments, ...). The remaining
punctuation and primitive-spelling fragments are:

[source,ebnf]
----
fragment GStringQuotationMark ::= '"'
fragment SqStringQuotationMark ::= "'"
fragment TdqStringQuotationMark ::= '"""'
fragment TsqStringQuotationMark ::= "'''"
fragment DollarSlashyGStringQuotationMarkBegin ::= '$/'
fragment DollarSlashyGStringQuotationMarkEnd   ::= '/$'
fragment DollarSlashEscape       ::= '$/'
fragment DollarDollarEscape      ::= '$$'
fragment DollarSlashDollarEscape ::= '$/$'
fragment DollarEscape            ::= '\\' '$'
fragment SlashEscape             ::= '\\' '/'
fragment Backslash               ::= '\\'
fragment Slash                   ::= '/'
fragment Dollar                  ::= '$'
fragment BOOLEAN ::= 'boolean'
fragment BYTE    ::= 'byte'
fragment CHAR    ::= 'char'
fragment DOUBLE  ::= 'double'
fragment FLOAT   ::= 'float'
fragment INT     ::= 'int'
fragment LONG    ::= 'long'
fragment SHORT   ::= 'short'
----

---

--- METRICS ---
- Files Extracted: 42
- Estimated Token Budget: ~139108 tokens
- Canonical Reference: https://codewiki.google/github.com/apache/groovy
