/* JavaCC grammar for the SLING-5449 content repository 
 * initialization language
 * See https://javacc.github.io/javacc/ for the most recent docs,
 *   including links to grammar examples
 * See http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm for a FAQ from 2011
 * See also http://eriklievaart.com/web/javacc1.html (from 2014) for additional information
 */
 
options
{
    STATIC=false;
    LOOKAHEAD=3;
    //FORCE_LA_CHECK=true;
    //DEBUG_PARSER=true;
    //DEBUG_LOOKAHEAD=true;
}

PARSER_BEGIN(RepoInitParserImpl)

package org.apache.sling.repoinit.parser.impl;

import java.util.List;
import java.util.ArrayList;

import org.apache.sling.repoinit.parser.operations.*;

/*
 * 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.
 */

public class RepoInitParserImpl 
{
}
PARSER_END(RepoInitParserImpl)

SKIP :
{
    " "
|   "\r"
|   "\t"
|   < COMMENT: "#" (~["\n"])* "\n" >
}

TOKEN:
{
    < SET: "set" >
|   < ACL: "ACL" >
|   < ACE: "ACE" >
|   < ON: "on" >
|   < TO: "to" >
|   < FROM: "from" >
|   < REMOVE: "remove" >
|   < ALLOW: "allow" >
|   < DENY: "deny" >
|   < FOR: "for" >
|   < CREATE: "create" >
|   < DELETE: "delete" >
|   < DISABLE: "disable" >
|   < SERVICE: "service" >
|   < ADD: "add" >
|   < MIXIN: "mixin" >
|   < PATH: "path" >
|   < END: "end" >
|   < REPOSITORY: "repository" >
|   < PRINCIPAL: "principal" >
|   < USER: "user" >
|   < GROUP: "group" >
|   < NODETYPES: "nodetypes" >
|   < REGISTER: "register" >
|   < NAMESPACE: "namespace" >
|   < PRIVILEGE: "privilege" >
|   < WITH: "with" >
|   < ABSTRACT: "abstract" >
|   < PASSWORD: "password" >
|   < START_TEXTBLOCK: "<<===" > : TEXTBLOCK
|   < LPAREN: "(" >
|   < RPAREN: ")" >
|   < LCURLY: "{" >
|   < RCURLY: "}" >
|   < MULTI: "[]" >
|   < COMMA: "," >
|   < DQUOTE: "\"" >
|   < COLON: ":" >
|   < STAR: "*" >
|   < EQUALS: "=" >
|   < RESTRICTION: "restriction" >
|   < ACL_OPTIONS: "ACLOptions" >
|   < PROPERTIES: "properties" >
|   < SETDEF: "default" >
|   < FORCED: "forced" >

/* The order of these fuzzy statements is important (first match wins?) */ 
|   < NAMESPACED_ITEM: (["a"-"z"] | ["A"-"Z"])+ ":" (["a"-"z"] | ["A"-"Z"])+ >
|   < PATH_STRING: "/" (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | ["-"] | ["_"] | ["."] | ["@"] | [":"] | ["+"] | ["/"]) * >
|   < PATH_REPOSITORY: ":repository" >
|   < STRING: (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | ["-"] | ["_"] | ["."] | ["/"] | [":"] | ["*"]) + >
|   < EOL: "\n" >
}

/* Found out about this syntax later - would make STRING etc. simpler */
TOKEN: {
<QUOTED: 
    <DQUOTE>
    (
         "\\" ~[]     // escaped chars
    |
        ~["\\","\""]  //any char but not backslash nor quote
    )* 
    <DQUOTE>
    > 
}

<TEXTBLOCK> SKIP : 
{
    "\r"
}

<TEXTBLOCK> TOKEN :
{
    < TEXT : ~[] > 
|   < END_TEXTBLOCK: "===>>" > : DEFAULT
} 

List<Operation> parse() :
{}
{
    { final List<Operation> result = new ArrayList<Operation>(); }
    
    ( 
        serviceUserStatement(result) 
        | setAclPaths(result) 
        | setAclPrincipals(result)
        | setAclPrincipalBased(result)
        | setAclRepository(result)
        | deleteAclPaths(result) 
        | deleteAclPrincipals(result)
        | deleteAclPrincipalBased(result)
        | removeAcePaths(result) 
        | removeAcePrincipals(result)
        | removeAcePrincipalBased(result)
        | createPathStatement(result)
        | addMixins(result)
        | removeMixins(result)
        | registerNamespaceStatement(result)
        | registerNodetypesStatement(result)
        | registerPrivilegeStatement(result)
        | createGroupStatement(result)
        | deleteGroupStatement(result)
        | createUserStatement(result)
        | deleteUserStatement(result)
        | disableUserStatement(result)
        | addToGroupStatement(result)
        | removeFromGroupStatement(result)
        | setPropertiesStatement(result)
        | blankLine() 
    ) * 
    <EOF>
    
    { return result; }
}

void blankLine() :
{}
{
    <EOL>
}

List<String> principalsList() :
{
    Token t = null;
    List<String> principals = new ArrayList<String>(); 
}
{
    t = quotableString() { principals.add(t.image); } 
    ( <COMMA> t = quotableString() { principals.add(t.image); } )* 
    { return principals; }
}

WithPathOptions withPathStatement() :
{
    Token path = null;
    Token forced = null;
}
{
    /* accept relative (string) or absolute path */
    <WITH> (forced=<FORCED>)? <PATH> ( path=<STRING> | path=<PATH_STRING> )
    { return new WithPathOptions(path.image, forced != null); }
}

void serviceUserStatement(List<Operation> result) :
{
    Token t;
    List<String> principals;
    WithPathOptions wpopt = null;
}
{
    (t=<CREATE> | t=<DELETE>) 
    <SERVICE> <USER> 
    principals = principalsList() 
    ( wpopt = withPathStatement() ) ?
    (<EOL> | <EOF>)
    
    {
        for(String principal : principals) {
            if(CREATE == t.kind) {
                result.add(new CreateServiceUser(principal, wpopt));
            } else {
                result.add(new DeleteServiceUser(principal));
            }
        } 
    }
}

List<String> namespacedItemsList() :
{
    Token t = null;
    List<String> priv = new ArrayList<String>(); 
    
}
{
    t = <NAMESPACED_ITEM> { priv.add(t.image); } 
    ( <COMMA> t = <NAMESPACED_ITEM> { priv.add(t.image); } )* 
    { return priv; }
}

List<String> privilegesList() :
{
    Token t = null;
    List<String> priv = new ArrayList<String>();
}
{
    ( t=<NAMESPACED_ITEM> | t=<STRING> ) { priv.add(t.image); }
    ( <COMMA> ( t=<NAMESPACED_ITEM> | t=<STRING> ) { priv.add(t.image); } )*
    { return priv; }
}

String usernameList() :
{
    List<String> names = new ArrayList<String>();
    Token t = null;
}
{
    ( t = quotableString() ) { names.add(t.image); }
    // disable lists for now, not supported downstream
    // ( <COMMA> t = <STRING> { names.add(t.image); }) *

    {
        return String.join(",", names);
    }
}

String pathExpression() : 
{
    Token t = null;
    Token tf = null;
    String usernames = null;
    final StringBuilder sb = new StringBuilder();
}
{
    ( 
        tf = <STRING> <LPAREN> usernames = usernameList() <RPAREN> ( t = <PATH_STRING> ) ? 
        | ( t = <PATH_STRING> 
        | t = <PATH_REPOSITORY> )
    )
    { 
        if(tf != null) {
            sb.append(':').append(tf.image).append(':').append(usernames).append('#');
        }
        if(t != null) {
            sb.append(t.image);
        }
    }

    { return sb.toString(); }
}

List<String> pathsList() :
{
    String pathExpr = null;
    List<String> paths = new ArrayList<String>();
}
{
    ( pathExpr = pathExpression() ) { paths.add(pathExpr); }
    ( <COMMA> ( pathExpr = pathExpression() ) { paths.add(pathExpr); } )*
    { return paths; }
}

void createPathStatement(List<Operation> result) :
{
    CreatePath cp = null;
    String defaultPrimaryType = null;
    Token t1 = null;
    Token t2 = null;
    List<String> t3 = null;
    List<PropertyLine> lines = new ArrayList<PropertyLine>();
}
{
    <CREATE> <PATH> 
    ( <LPAREN> t1 = <NAMESPACED_ITEM> <RPAREN> { defaultPrimaryType = t1.image; } ) ?
    
    ( t1 = <PATH_STRING> ( <LPAREN> t2 = <NAMESPACED_ITEM> <RPAREN> ) ?
                         ( <LPAREN> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ?
                         ( <LPAREN> t2 = <NAMESPACED_ITEM> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ?
        {
            if(cp == null) {
                cp = new CreatePath(defaultPrimaryType);
            } 
            cp.addSegment(t1.image, t2 == null ? null : t2.image, t3);
            t2 = null;
            t3 = null;
        }
    ) +
    ( <WITH> <PROPERTIES> <EOL>
      ( propertyLine(lines) | blankLine() ) +
      {
        cp.setPropertyLines(lines);
      }
      <END>
    )?
    (<EOL> | <EOF>)
    
    { if(cp != null) result.add(cp); }
}

void addMixins(List<Operation> result) :
{
    List<String> mixins = null;
    List<String> paths = null;
}
{
    <ADD> <MIXIN>
    mixins = namespacedItemsList()
    <TO>
    paths = pathsList()

    {
        result.add(new AddMixins(mixins, paths));
    }
}

void removeMixins(List<Operation> result) :
{
    List<String> mixins = null;
    List<String> paths = null;
}
{
    <REMOVE> <MIXIN>
    mixins = namespacedItemsList()
    <FROM>
    paths = pathsList()

    {
        result.add(new RemoveMixins(mixins, paths));
    }
}

void setAclPaths(List<Operation> result) :
{
    List<String> paths;
    List<AclLine> lines = new ArrayList<AclLine>();
    List<String> aclOptions;
} 
{
    <SET> <ACL> <ON> paths  = pathsList() aclOptions=aclOptions() <EOL>
    ( removeStarLine(lines) | userPrivilegesLine(lines, true) | blankLine() ) +
    <END> 
    ( <EOL> | <EOF> )
    
    {
        result.add(new SetAclPaths(paths, lines, aclOptions));
    }
}

void removeStarLine(List<AclLine> lines) : 
{
    List<String> tmp = null;
    AclLine line = new AclLine(AclLine.Action.REMOVE_ALL);
}
{
    <REMOVE> <STAR> 
    (
        <FOR> tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); }
        
        | <ON> tmp = pathsList() { line.setProperty(AclLine.PROP_PATHS, tmp); }
    )     
    <EOL>
    
    {
        lines.add(line);
    }
}

AclLine privilegesLineOperation(boolean supportsRemoveAction) :
{  
}
{
    ( 
        <REMOVE>        { 
if (supportsRemoveAction) { 
    return new AclLine(AclLine.Action.REMOVE); 
} else { 
    throw new ParseException("REMOVE action not supported with 'remove acl' statements.");
}}
        | ( <ALLOW>     { return new AclLine(AclLine.Action.ALLOW); } )
        | ( <DENY>      { return new AclLine(AclLine.Action.DENY); } )    
    ) 
}

void userPrivilegesLine(List<AclLine> lines, boolean supportsRemoveAction) :
{
    AclLine line;
    List<String> tmp;
    List<RestrictionClause> restrictions;
}
{
    line = privilegesLineOperation(supportsRemoveAction)
    tmp = privilegesList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); }
    <FOR>
    tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); }
    restrictions = restrictions()  { line.setRestrictions(restrictions); }
    <EOL>

    {   
        lines.add(line); 
    }
}
/**
 * A single restriction value
 */
void restrictionValue(List<String> values) :
{
   Token t;
}
{
   <COMMA> ( t=<STAR> | t=<NAMESPACED_ITEM> | t=<PATH_STRING> | t=<STRING> )
   {
       values.add(t.image);
   }
}

/**
 * A list of restriction values
 */
List<String> restrictionValues() :
{
    List<String> values = new ArrayList<String>();
}
{
    ( restrictionValue(values) ) *

    {
        return values;
    }

}


/**
 * A single restriction
 */
void restriction(List<RestrictionClause> restrictions) :
{
  Token restrictionProp;
  List<String> values;
}
{
  <RESTRICTION>
  <LPAREN> restrictionProp=<NAMESPACED_ITEM> values=restrictionValues()  <RPAREN>

  {
      restrictions.add(new RestrictionClause(restrictionProp.image,values));
  }
}

/**
 * A list of restrictions
 */
List<RestrictionClause> restrictions() :
{
    List<RestrictionClause> restrictions = new ArrayList<RestrictionClause>();
}
{
   ( restriction(restrictions) )*

   {
       return restrictions;
   }
}

void pathPrivilegesLine(List<AclLine> lines, boolean supportsRemoveAction) : 
{
    AclLine line;
    List<String> tmp;
    List<RestrictionClause> restrictions;
}
{
    line = privilegesLineOperation(supportsRemoveAction)
    tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); } 
    <ON> tmp = pathsList() { line.setProperty(AclLine.PROP_PATHS, tmp); }
    ( <NODETYPES> tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_NODETYPES, tmp); }) ?
     restrictions = restrictions()  { line.setRestrictions(restrictions); }
    <EOL>
    
    {    
        lines.add(line); 
    }
}
void aclOption(List<String> options) :
{
   Token t;
}
{
    (t=<NAMESPACED_ITEM> | t=<STRING>)
    {
        options.add(t.image);
    }
}
List<String> aclOptions() :
{
    List<String> aclOptionList = new ArrayList<String>();
    Token t;
}
{
    ( <LPAREN> <ACL_OPTIONS> <EQUALS> aclOption(aclOptionList) ( <COMMA> aclOption(aclOptionList) )*  <RPAREN> )?

    {
       return aclOptionList;
    }
}

void setAclRepository(List<Operation> result) :
{
    List<AclLine> lines = new ArrayList<AclLine>();
    List<String> principals;
    List<String> privileges;
    List<String> aclOptions;
    AclLine line = null;

}
{
    <SET> <REPOSITORY> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL>
    (
        ( <REMOVE> <STAR> )
            {
                line = new AclLine(AclLine.Action.REMOVE_ALL);
                lines.add(line);
            }
        | ( line = privilegesLineOperation(true) privileges = namespacedItemsList() )
            {
                line.setProperty(AclLine.PROP_PRIVILEGES, privileges);
                lines.add(line);
            }
        | ( blankLine() )
    )+
    <END>
    ( <EOL> | <EOF> )

    {
        result.add(new SetAclPrincipals(principals, lines, aclOptions));
    }
}

void setAclPrincipals(List<Operation> result) :
{
    List <String> principals;
    List<AclLine> lines = new ArrayList<AclLine>();
    List<String> aclOptions;
}
{
    <SET> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL>
    ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) +
    <END> 
    ( <EOL> | <EOF> )
    
    {
        result.add(new SetAclPrincipals(principals, lines, aclOptions));
    }
}

void setAclPrincipalBased(List<Operation> result) :
{
    List <String> principals;
    List<AclLine> lines = new ArrayList<AclLine>();
    List<String> aclOptions;
}
{
    <SET> <PRINCIPAL> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL>
    ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) +
    <END>
    ( <EOL> | <EOF> )

    {
        result.add(new SetAclPrincipalBased(principals, lines, aclOptions));
    }
}

void removeAcePaths(List<Operation> result) :
{
    List<String> paths;
    List<AclLine> lines = new ArrayList<AclLine>();
} 
{
    <REMOVE> <ACE> <ON> paths  = pathsList()<EOL>
    ( userPrivilegesLine(lines, false) | blankLine() ) +
    <END> 
    ( <EOL> | <EOF> )
    
    {
    result.add(new RemoveAcePaths(paths, lines));
}
}

void removeAcePrincipals(List<Operation> result) :
{
    List <String> principals;
    List<AclLine> lines = new ArrayList<AclLine>();
}
{
    <REMOVE> <ACE> <FOR> principals = principalsList()<EOL>
    ( pathPrivilegesLine(lines, false) | blankLine() ) +
    <END> 
    ( <EOL> | <EOF> )
    
    {
    result.add(new RemoveAcePrincipals(principals, lines));
}
}

void removeAcePrincipalBased(List<Operation> result) :
{
    List <String> principals;
    List<AclLine> lines = new ArrayList<AclLine>();
}
{
    <REMOVE> <PRINCIPAL> <ACE> <FOR> principals = principalsList()<EOL>
    ( pathPrivilegesLine(lines, false) | blankLine() ) +
    <END>
    ( <EOL> | <EOF> )

    {
    result.add(new RemoveAcePrincipalBased(principals, lines));
}
}

void deleteAclPaths(List<Operation> result) :
{
    List<String> paths;
} 
{
    <DELETE> <ACL> <ON> paths  = pathsList()
    ( <EOL> | <EOF> )  
    {
        result.add(new DeleteAclPaths(paths));
    }
}

void deleteAclPrincipals(List<Operation> result) :
{
    List <String> principals;
}
{
    <DELETE> <ACL> <FOR> principals = principalsList()
    ( <EOL> | <EOF> )
    {
        result.add(new DeleteAclPrincipals(principals));
    }
}

void deleteAclPrincipalBased(List<Operation> result) :
{
    List <String> principals;
}
{
    <DELETE> <PRINCIPAL> <ACL> <FOR> principals = principalsList()
    ( <EOL> | <EOF> )
    {
        result.add(new DeleteAclPrincipalBased(principals));
    }
}

void registerNamespaceStatement(List<Operation> result) :
{
    Token prefix = null;
    Token uri;
}
{
    <REGISTER> <NAMESPACE> 
    <LPAREN> prefix = <STRING> <RPAREN> 
    uri = quotableString()

    {
        result.add(new RegisterNamespace(prefix.image, uri.image)); 
    }
    
    (<EOL> | <EOF>)
}

void registerPrivilegeStatement(List<Operation> result) :
{
    Token privilege;
    boolean isAbstract = false;
    List<String> aggregates = new ArrayList<String>();
}
{
    <REGISTER> ((<ABSTRACT>) {isAbstract = true;})? <PRIVILEGE> (privilege = <STRING> | privilege = <NAMESPACED_ITEM>) (<WITH> aggregates = privilegesList())?
    {
        result.add(new RegisterPrivilege(privilege.image, isAbstract, aggregates));
    }
    (<EOL> | <EOF>)
}

void textBlock(StringBuilder b) : 
{
    Token t;
}
{
    <START_TEXTBLOCK>
    ( t = <TEXT> { b.append(t.image); } )*
    <END_TEXTBLOCK>
}

void registerNodetypesStatement(List<Operation> result) :
{
    StringBuilder b = new StringBuilder();
}
{
    <REGISTER> <NODETYPES> <EOL> 
    textBlock(b) 
    (<EOL> | <EOF>)
    {
        result.add(new RegisterNodetypes(b.toString()));
    }
}

void createGroupStatement(List<Operation> result) :
{
    Token group = null;
    Token encoding = null;
    WithPathOptions wpopt = null;
}
{
    <CREATE> <GROUP> 
    ( group = quotableString() )
    ( wpopt = withPathStatement() ) ?

    {
        result.add(new CreateGroup(group.image, wpopt));
    }
}

void deleteGroupStatement(List<Operation> result) :
{
    Token group = null;
}
{
    <DELETE> <GROUP> 
    ( group = quotableString() )

    {
        result.add(new DeleteGroup(group.image));
    }
}

void createUserStatement(List<Operation> result) :
{
    Token user = null;
    Token encoding = null;
    Token password = null;
    WithPathOptions wpopt = null;
}
{
    <CREATE> <USER> 
    ( user = <STRING> )
    ( wpopt = withPathStatement() ) ?
    ( <WITH> <PASSWORD> ( <LCURLY> encoding = <STRING> <RCURLY> )? password = <STRING> )?

    {
        result.add(new CreateUser(user.image, 
            (encoding == null ? null : encoding.image), 
            (password == null ? null : password.image),
            wpopt
        ));
    }
}

void deleteUserStatement(List<Operation> result) :
{
    Token user = null;
}
{
    <DELETE> <USER> 
    ( user = <STRING> )

    {
        result.add(new DeleteUser(user.image));
    }
}

Token quotedString() :
{
    Token t = null;
}
{
    ( t = <QUOTED> )
    {
        // Remove start/end quotes + escaping backslash for double quotes
        final String unescaped = t.image.trim()
            .replaceAll("^\"|\"$", "")
            .replaceAll("\\\\\"", "\"")
            .replaceAll("\\\\\\\\", "\\\\")
        ;
        return new Token(t.kind, unescaped);
    }
}

void disableUserStatement(List<Operation> result) :
{
    Token user = null;
    Token msg = null;
    Token isServiceUser = null;
}
{
    <DISABLE> ( isServiceUser = <SERVICE> )? <USER>
    ( user = <STRING> )
    ( <COLON> msg = quotedString() )
    {
        DisableServiceUser dsu = new DisableServiceUser(user.image, msg.image);
        dsu.setServiceUser(isServiceUser != null);
        result.add(dsu);
    }
}

void addToGroupStatement(List<Operation> result) :
{
    List <String> members;
    Token t;
    Token group = null;
}
{
    <ADD>
    members =  principalsList()
    <TO> <GROUP>
    group = quotableString()

    {
        result.add(new AddGroupMembers(members, group.image));
    }
}

void removeFromGroupStatement(List<Operation> result) :
{
    List <String> members;
    Token t;
    Token group = null;
}
{
    <REMOVE>
    members =  principalsList()
    <FROM> <GROUP>
    group = quotableString()

    {
        result.add(new RemoveGroupMembers(members, group.image));
    }
}

Token quotableString() :
{
    Token t = null;
}
{
    (t = <STRING> | t = quotedString() ) { return t; }
}

Token propertyValue() :
{
    Token t = null;
}
{
    (t = <STRING> | t = quotedString() | t = <PATH_STRING> | t = <NAMESPACED_ITEM> ) { return t; }
}

List<String> propertyValuesList() :
{
    Token t = null;
    List<String> values = new ArrayList<String>();
}
{
    (( t = propertyValue() ) { values.add(t.image); })?
    ( <COMMA> ( t = propertyValue() ) { values.add(t.image); } )*
    { return values; }
}

void propertyLine(List<PropertyLine> lines) :
{
    Token name = null;
    Token type = null;
    List<String> values;
    Token t = null;
    boolean isDefault = false;
}
{
    (t = <SET> | t = <SETDEF> {isDefault = true;} )
    ( name = <STRING> | name = <NAMESPACED_ITEM>)
    ( <LCURLY> ( type = <STRING> ) <RCURLY> | <LCURLY> ( type = <STRING> ) <MULTI> <RCURLY> )?
    <TO> ( values = propertyValuesList() )
    <EOL>
    {
        lines.add(new PropertyLine(name.image, type == null ? null : type.image, values, isDefault));
    }
}

void setPropertiesStatement(List<Operation> result) :
{
    List<PropertyLine> lines = new ArrayList<PropertyLine>();
    List<String> paths;
}
{
    <SET> <PROPERTIES> <ON>  ( paths  = pathsList() ) <EOL>
    ( propertyLine(lines) | blankLine() ) +
    <END>
    ( <EOL> | <EOF> )
    {
        result.add(new SetProperties(paths, lines));
    }
}