All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.protobufel.grammar.ParserUtils Maven / Gradle / Ivy

There is a newer version: 0.7.1
Show newest version
//
// Copyright © 2014, David Tesler (https://github.com/protobufel)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the  nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package com.github.protobufel.grammar;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenSource;

import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Message;

/**
 * Utilities for dealing with comments, needed for the SourceInfo generation.
 * @author [email protected] David Tesler
 */
final class ParserUtils {
  private static final Pattern LINE_FINDER = Pattern.compile("\\n");
  private static final Pattern BLOCK_COMMENT_PROTO_STRIPPER = Pattern.compile(
      "^[\\s&&[^\\n]]*(?:[*]|[\\s&&[^\\n\\r]]|\\r(?=.))", Pattern.MULTILINE | Pattern.UNIX_LINES);

  private ParserUtils() {}

  /**
   * Returns the block comment body stripped of leading whitespace and * in all but the first line,
   * and the block comments delimiters removed.
   * 
   * @param blockComment a C-style block comment
   * @return the comment's body with all but the first line specially trimmed
   */
  public static String getTrimmedBlockCommentContent(final String blockComment) {
    final String content = blockComment.substring(0, blockComment.length() - 2);
    return BLOCK_COMMENT_PROTO_STRIPPER.matcher(content).replaceAll("").substring(2);
  }

  /**
   * Gets a zero-based line count of text.
   * 
   * @param text a string in which to count lines
   * @return a number of {@code \n} new lines in the text
   */
  public static int getLineCount(final String text) {
    final Matcher matcher = LINE_FINDER.matcher(text);
    int i = 0;

    while (matcher.find()) {
      i++;
    }

    return i;
  }

  public static int getEndPositionInLine(final Token token) {
    return token.getCharPositionInLine() + token.getStopIndex() - token.getStartIndex() + 1;
  }

  public static int getTotalFieldCount(final Message.Builder builder) {
    int count = 0;

    for (final FieldDescriptor field : builder.getDescriptorForType().getFields()) {
      if (field.isRepeated()) {
        count += builder.getRepeatedFieldCount(field);
      } else if (builder.hasField(field)) {
        count++;
      }
    }

    return count;
  }

  public static final class CommonTokenStreamEx extends CommonTokenStream {

    public CommonTokenStreamEx(final TokenSource tokenSource) {
      super(tokenSource);
    }

    public Token nextToken(final int i, final int channel) {
      final int tokenIndex = super.nextTokenOnChannel(i, channel);
      return tokenIndex == -1 ? null : tokens.get(tokenIndex);
    }

    public Token previousToken(final int i, final int channel) {
      final int tokenIndex = super.previousTokenOnChannel(i, channel);
      return tokenIndex == -1 ? null : tokens.get(tokenIndex);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy