/*
 * Copyright (C) 2016 Francis Galiegue <fgaliegue@gmail.com>
 *
 * Licensed 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.
 */

package com.github.fge.grappa.parsers;

import com.github.fge.grappa.rules.Action;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

import javax.annotation.Nonnull;
import java.util.Objects;

/**
 * A {@link BaseParser} with an attached {@link EventBus}
 *
 * <p>This parser allows you to register instances of classes with methods which
 * have subscribed to a bus using Guava's {@link Subscribe} annotation. For the
 * recall, such methods must obey the following criteria:</p>
 *
 * <ul>
 *     <li>they must be public,</li>
 *     <li>they must return {@code void},</li>
 *     <li>they must accept one, and only one, argument.</li>
 * </ul>
 *
 * <p>Since Grappa allows you to build basically anything during a parsing run,
 * you may use it, for instance, to post elements you would push on the stack
 * "ahead of time". Or, even more simple, you'd just post an event each time you
 * have a match for a certain rule, with the text matched. For instance:</p>
 *
 * <pre>
 *     public Rule someRule()
 *     {
 *         // will trigger on any subscribed method having a String as an
 *         // argument, since match() returns a String
 *         return sequence("foobar", post(match()));
 *     }
 * </pre>
 *
 * <p>You can, of course, do more than that.</p>
 *
 * <p>The method to post on the bus ({@link #post(Object)}, of which there is
 * an example above) is basically an {@link Action}, and as such obeys all rules
 * of an action; unlike what happens with the parser stack however, if you are
 * in a predicate and allow actions, the objects you post on the bus cannot be
 * "rolled back", for obvious reasons. You may still detect whether you are in
 * an action and post anyway as follows:</p>
 *
 * <pre>
 *     public boolean postNoPredicate(final Object object)
 *     {
 *         if (!inPredicate())
 *             post(object);
 *         return true;
 *     }
 * </pre>
 *
 * <h2>Usage notes</h2>
 *
 * <p>You can only register listeners to such a parser once the parser has been
 * created, and they <em>must</em> be created before the parser is run on an
 * input. For instance:</p>
 *
 * <pre>
 *     // MyParser extends EventBusParser
 *     final MyParser parser = Grappa.createParser(MyParser.class);
 *
 *     final MyListener listener = new MyListener();
 *     parser.register(listener);
 *
 *     // Crete a runner, run on an input
 * </pre>
 *
 * <p>If you reuse the same parser again on different inputs, then your listener
 * will be reused again, so be careful about it being state dependent (this may
 * be a desired effect however; this is up to you to decide).</p>
 *
 * @see Subscribe
 * @see EventBus#register(Object)
 * @see EventBus#post(Object)
 */
public abstract class EventBusParser<V>
    extends BaseParser<V>
{
    protected final EventBus bus = new EventBus();

    /**
     * Register a listener to the event bus
     *
     * @param listener the listener
     * @return always true
     *
     * @see EventBus#register(Object)
     */
    public final boolean register(@Nonnull final Object listener)
    {
        bus.register(Objects.requireNonNull(listener));
        return true;
    }

    /**
     * Post an arbitrary, non null, object on the bus
     *
     * @param object the object (must not be null)
     * @return always true
     */
    public final boolean post(@Nonnull final Object object)
    {
        Objects.requireNonNull(object);
        bus.post(object);
        return true;
    }
}

@@ -656,16 +656,82 @@
 rsers;%0A%0A
+import com.github.fge.grappa.annotations.SkipActionsInPredicates;%0A
 import c
@@ -1382,281 +1382,83 @@
  %3Cp%3E
-Since Grappa allows you to build basically anything during a parsing run,%0A * you may use it, for instance, to post elements you would push on the stack%0A * %22ahead of time%22. Or, even more simple, you'd just post an event each time you%0A * have a match for a certain rule
+A sample usage is shown below, where an event is posted on the bus
 , with
+%0A *
  the
@@ -1470,30 +1470,31 @@
  matched
-. For instance
+ as an argument
 :%3C/p%3E%0A *
@@ -1756,196 +1756,98 @@
  %3Cp%3E
-You can, of course, do more than that.%3C/p%3E%0A *%0A * %3Cp%3EThe method to post on the bus (%7B@link #post(Object)%7D, of which there is%0A * an example above) is basically an %7B@link Action%7D, and as such
+This method (%7B@link #post(Object)%7D ultimately becomes an %7B@link Action%7D,%0A * which means it
  obe
@@ -1857,16 +1857,17 @@
 all 
+the 
 rules
-%0A *
  of 
@@ -1879,456 +1879,137 @@
 tion
-; unlike what happens with the parser stack however, if you are%0A * in a predicate and allow actions, the objects you post on the bus cannot be%0A * %22rolled back%22, for obvious reasons. You may still detect whether you are in%0A * an action and post anyway as follows:%3C/p%3E%0A *%0A * %3Cpre%3E%0A *     public boolean postNoPredicate(final Object object)%0A *     %7B%0A *         if (!inPredicate())%0A *             post(object);%0A *         return true;%0A *     %7D%0A * 
+. This includes, for instance,%0A * the presence (or absence thereof) of annotations such as %7B@link%0A * SkipActionsInPredicates%7D.
 %3C/p
-re
 %3E%0A *
@@ -2046,31 +2046,9 @@
  %3Cp%3E
-You can only register l
+L
 iste
@@ -2069,16 +2069,39 @@
  parser 
+can only be registered 
 once the
@@ -2131,83 +2131,8 @@
 ated
-, and they %3Cem%3Emust%3C/em%3E be created before the parser is run on an%0A * input
 . Fo
@@ -2268,24 +2268,54 @@
 .class);%0A *%0A
+ *     // Create the listener%0A
  *     final
@@ -2355,16 +2355,55 @@
 ener();%0A
+ *%0A *     // Register it to the parser%0A
  *     p
@@ -2496,223 +2496,207 @@
  %3Cp%3E
-If you reuse the same parser again on different inputs, then your listener%0A * will be reused again, so be careful about it being state dependent (this may%0A * be a desired effect however; this is up to you to decide)
+Please note that such a listener's state, if any, will be retained across%0A * reuses of the same parser on different inputs. According to the use case,%0A * this may, or may not, be a desirable property
 .%3C/p

update documentation