/* 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" >
|   < ENSURE: "ensure" >
|   < SERVICE: "service" >
|   < ADD: "add" >
|   < MIXIN: "mixin" >
|   < PATH: "path" >
|   < NODE: "node" >
|   < NODES: "nodes" >
|   < 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)
        | ensureAclPrincipalBased(result)
        | setAclRepository(result)
        | deleteAclPaths(result) 
        | deleteAclPrincipals(result)
        | deleteAclPrincipalBased(result)
        | removeAcePaths(result) 
        | removeAcePrincipals(result)
        | removeAcePrincipalBased(result)
        | createPathStatement(result)
        | ensureNodesStatement(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); }
}

// similar to createPath but with stricter semantics of also changing types of existing nodes
void ensureNodesStatement(List<Operation> result) :
{
    EnsureNodes en = null;
    String defaultPrimaryType = null;
    Token t1 = null;
    Token t2 = null;
    List<String> t3 = null;
    List<PropertyLine> lines = new ArrayList<PropertyLine>();
}
{
    <ENSURE> <NODES> 
    ( <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(en == null) {
                en = new EnsureNodes(defaultPrimaryType);
            } 
            en.addSegment(t1.image, t2 == null ? null : t2.image, t3);
            t2 = null;
            t3 = null;
        }
    ) +
    ( <WITH> <PROPERTIES> <EOL>
      ( propertyLine(lines) | blankLine() ) +
      {
        en.setPropertyLines(lines);
      }
      <END>
    )?
    (<EOL> | <EOF>)
    
    { if(en != null) result.add(en); }
}

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 ensureAclPrincipalBased(List<Operation> result) :
{
    List <String> principals;
    List<AclLine> lines = new ArrayList<AclLine>();
    List<String> aclOptions;
}
{
    <ENSURE> <PRINCIPAL> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL>
    ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) +
    <END>
    ( <EOL> | <EOF> )

    {
        result.add(new EnsureAclPrincipalBased(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));
    }
}