protected override object Read(PushbackTextReader r, char caret, object opts, object pendingForms)
{
int startLine = -1;
int startCol = -1;
LineNumberingTextReader lntr = r as LineNumberingTextReader;
if (lntr != null)
{
startLine = lntr.LineNumber;
startCol = lntr.ColumnNumber;
}
pendingForms = EnsurePending(pendingForms);
IPersistentMap metaAsMap;
{
object meta = ReadAux(r, opts, pendingForms);
if (meta is Symbol || meta is String)
metaAsMap = RT.map(RT.TagKey, meta);
else if (meta is Keyword)
metaAsMap = RT.map(meta, true);
else if ((metaAsMap = meta as IPersistentMap) == null)
throw new ArgumentException("Metadata must be Symbol,Keyword,String or Map");
}
object o = ReadAux(r, opts, pendingForms);
if (o is IMeta)
{
if (startLine != -1 && o is ISeq)
metaAsMap = metaAsMap.assoc(RT.LineKey, startLine)
.assoc(RT.ColumnKey, startCol)
.assoc(RT.SourceSpanKey, RT.map(
RT.StartLineKey, startLine,
RT.StartColumnKey, startCol,
RT.EndLineKey, lntr.LineNumber,
RT.EndColumnKey, lntr.ColumnNumber));
IReference iref = o as IReference;
if (iref != null)
{
iref.resetMeta(metaAsMap);
return o;
}
object ometa = RT.meta(o);
for (ISeq s = RT.seq(metaAsMap); s != null; s = s.next())
{
IMapEntry kv = (IMapEntry)s.first();
ometa = RT.assoc(ometa, kv.key(), kv.val());
}
return ((IObj)o).withMeta((IPersistentMap)ometa);
}
else
throw new ArgumentException("Metadata can only be applied to IMetas");
}