code: /*
  * Copyright 2014 Basis Technology Corp.
  *
  * 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.basistech.tclre;
  
  import com.google.common.base.MoreObjects;
  
  import java.io.Serializable;
  import java.util.Collections;
  import java.util.EnumSet;
  
  /**
   * A compiled regular expression. The method {@link #compile(String, PatternFlags...)} serves
   * as the factory.
   * @see com.basistech.tclre.RePattern
   * @see com.basistech.tclre.ReMatcher
   */
  public class HsrePattern implements RePattern, Serializable {
      static final long serialVersionUID = 1L;
      final long info;
      final int nsub;       /* number of subexpressions */
      final Guts guts;
      final String original;
      final EnumSet<PatternFlags> originalFlags;
  
      HsrePattern(String original, EnumSet<PatternFlags> originalFlags, long info, int nsub, Guts guts) {
          this.original = original;
          this.originalFlags = originalFlags;
          this.info = info;
          this.nsub = nsub;
          this.guts = guts;
      }
  
      /**
       * Compile a pattern.
       * @param pattern the pattern.
       * @param flags flags that determine the interpretation of the pattern.
       * @return the compiled pattern.
       * @throws RegexException regex exception
       */
      public static RePattern compile(String pattern, EnumSet<PatternFlags> flags) throws RegexException {
          return Compiler.compile(pattern, flags);
      }
  
      /**
       * Compile a pattern.
       * @param pattern the pattern.
       * @param flags flags that determine the interpretation of the pattern.
       * @return the compiled pattern.
       * @throws RegexException regex exception
       */
      public static RePattern compile(String pattern, PatternFlags... flags) throws RegexException {
          EnumSet<PatternFlags> flagSet = EnumSet.noneOf(PatternFlags.class);
          Collections.addAll(flagSet, flags);
          return Compiler.compile(pattern, flagSet);
      }
  
      @Override
      public HsreMatcher matcher(CharSequence data, ExecFlags... flags) {
          EnumSet<ExecFlags> flagSet = EnumSet.noneOf(ExecFlags.class);
          Collections.addAll(flagSet, flags);
          try {
              return new HsreMatcher(this, data, flagSet);
          } catch (RegexException e) {
              // the idea is that we've done all the error detection before.
              throw new RegexRuntimeException(e);
          }
  
      }
  
      @Override
      public HsreMatcher matcher(CharSequence data, EnumSet<ExecFlags> flags) {
          try {
              return new HsreMatcher(this, data, flags);
          } catch (RegexException e) {
              throw new RegexRuntimeException(e);
          }
      }
  
      @Override
      public String pattern() {
          return original;
      }
  
      @Override
      public EnumSet<PatternFlags> flags() {
          return originalFlags;
      }
  
      @Override
      public String toString() {
          return MoreObjects.toStringHelper(this)
                  .add("pattern", original)
                  .add("flags", originalFlags)
                  .toString();
      }
  }
  