com.github.protobufel.grammar.ParserUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of protobufel-grammar Show documentation
Show all versions of protobufel-grammar Show documentation
ProtoBuf Java Parser and FileDescriptor Builder
//
// 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);
}
}
}