# Parsing and writing SWIFT text

## Parser

```csharp
var parser = new SwiftParser();
// or
var parser = SwiftParser.Instance;
```

`SwiftParser` is thread-safe as a singleton. Creating `new SwiftParser()` per call is also supported (used in tests).

## Parse one message

```csharp
var errors = new List<ValidationError>();
SwiftMessage message = parser.GetMessage(swiftText, errors);
// optional: skip definition validation
SwiftMessage raw = parser.GetMessage(swiftText, errors, validate: false);
```

`GetMessage`:

1. Parses FIN blocks `{1:…}{2:…}{3:…}{4:…}{5:…}` and user blocks such as `{S:…}`.
2. Instantiates the typed class (`MT103`, `MT202COV`, …) via the message type in Block 2.
3. Unless `validate: false`, runs `message.Validate(errors)`.

The original text is stored on `message.Content`.

## Parse several messages

```csharp
List<SwiftMessage> batch = parser.GetMessages(
    concatenatedText,
    messagesDelimiter: (char)3, // or your delimiter
    parseError: errors,
    validate: true);
```

Empty segments after the split are skipped.

## Access fields after parse

Prefer typed properties on the MT class:

```csharp
var mt103 = (MT103)message;
string reference = mt103.SendersReference_20.Value;
// alias:
string same = mt103.Tag20_SendersReference.Value;
```

Generic access on Block 4:

```csharp
SwiftTag tag20 = message.GetTagByName("20");
SwiftTag tag32A = message.GetTagByNumber(32);
```

`GetTagByName` / `GetTagByNumber` return the **first** matching tag in Block 4.

## Write FIN text

```csharp
string fin = parser.GetMessageAsText(message);
```

This uses the current object model (blocks + tags), not `message.Content`. Edits you make on typed properties are reflected in the output.

## Identify the type

```csharp
string type = message.MessageType;          // "103"
bool is103 = message.IsMTType("103");       // must be exactly 3 characters
Type clr = message.GetType();               // typeof(MT103)
```

`IsMTType` throws if the argument is not length 3.

## SWIFT text conventions

- Block 4 tags are `:20:value` / `:32A:yyMMddCCCNNNNN,`
- Amounts use `,` as the decimal mark. Trailing comma means `.00` (`14551,`).
- Multiline tag values use the SWIFT line length rules already present in the source text.
- Block 2 input (you send): `{2:I103BANKUKZHAXXXN}`
- Block 2 output (you received): `{2:O1030805…}`

When building amounts in code, set `Amount`, `Currency`, and `Date` on the typed tag instead of concatenating the raw `32A` string.

## Round-trip

```csharp
var errors = new List<ValidationError>();
var parsed = parser.GetMessage(original, errors);
string again = parser.GetMessageAsText(parsed);
```

Unit tests compare trimmed text and sometimes normalize newlines. Line endings and optional empty lines in Block 4 can differ slightly from the source file.
