text: "use strict";
  
  const util = require( "../../util" );
  const __hasOwnProperty = Object.prototype.hasOwnProperty;
  
  // Checks that each label is defined only once within each scope.
  function reportDuplicateLabels( ast, session ) {
  
      let check;
  
      function checkExpressionWithClonedEnv( node, env ) {
  
          check( node.expression, util.clone( env ) );
  
      }
  
      check = session.buildVisitor( {
          rule( node ) {
  
              check( node.expression, {} );
  
          },
  
          choice( node, env ) {
  
              node.alternatives.forEach( alternative => {
  
                  check( alternative, util.clone( env ) );
  
              } );
  
          },
  
          action: checkExpressionWithClonedEnv,
  
          labeled( node, env ) {
  
              const label = node.label;
  
              if ( label && __hasOwnProperty.call( env, label ) ) {
  
                  const start = env[ label ].start;
  
                  session.error(
                      `Label "${ label }" is already defined at line ${ start.line }, column ${ start.column }.`,
                      node.location
                  );
  
              }
  
              check( node.expression, env );
  
              if ( label ) env[ label ] = node.location;
  
          },
  
          text: checkExpressionWithClonedEnv,
          simple_and: checkExpressionWithClonedEnv,
          simple_not: checkExpressionWithClonedEnv,
          optional: checkExpressionWithClonedEnv,
          zero_or_more: checkExpressionWithClonedEnv,
          one_or_more: checkExpressionWithClonedEnv,
          group: checkExpressionWithClonedEnv
      } );
  
      check( ast );
  
  }
  
  module.exports = reportDuplicateLabels;
  