blob: 3c091436106bf9a5ad4ff8284fb3ca4dd0c059f7 [file] [log] [blame]
/*
* Copyright (c) 2011 Google Inc.
*
* All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
* Public License v1.0 which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.google.eclipse.protobuf.model.util;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.BOOL;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.BYTES;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.DOUBLE;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.FIXED32;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.FIXED64;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.FLOAT;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.INT32;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.INT64;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.SFIXED32;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.SFIXED64;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.SINT32;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.SINT64;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.STRING;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.UINT32;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.UINT64;
import static com.google.eclipse.protobuf.protobuf.ModifierEnum.OPTIONAL;
import com.google.eclipse.protobuf.grammar.CommonKeyword;
import com.google.eclipse.protobuf.protobuf.ComplexType;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.Message;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.ScalarType;
import com.google.eclipse.protobuf.protobuf.ScalarTypeLink;
import com.google.eclipse.protobuf.protobuf.TypeLink;
import com.google.inject.Singleton;
/**
* Utility methods related to <code>{@link MessageField}</code>s.
*
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton public class MessageFields {
/**
* Indicates whether the modifier of the given field is <code>{@link ModifierEnum#OPTIONAL}</code>.
* @param field the given field.
* @return {@code true} if the modifier of the given field is "optional," {@code false} otherwise.
*/
public boolean isOptional(MessageField field) {
return OPTIONAL.equals(field.getModifier());
}
/**
* Indicates whether the type of the given field is primitive. Primitive types include: {@code double}, {@code float},
* {@code int32}, {@code int64}, {@code uint32}, {@code uint64}, {@code sint32}, {@code sint64}, {@code fixed32},
* {@code fixed64}, {@code sfixed32}, {@code sfixed64} and {@code bool}.
* @param field the given field.
* @return {@code true} if the type of the given field is primitive, {@code false} otherwise.
*/
public boolean isPrimitive(MessageField field) {
TypeLink link = field.getType();
if (!(link instanceof ScalarTypeLink)) {
return false;
}
String typeName = ((ScalarTypeLink) link).getTarget().getName();
return !STRING.hasValue(typeName) && !BYTES.hasValue(typeName);
}
/**
* Indicates whether the given field is of type {@code bool}.
* @param field the given field.
* @return {@code true} if the given field is of type {@code bool}, {@code false} otherwise.
*/
public boolean isBool(MessageField field) {
return isScalarType(field, BOOL);
}
/**
* Indicates whether the given field is of type {@code bytes}.
* @param field the given field.
* @return {@code true} if the given field is of type {@code bytes}, {@code false} otherwise.
*/
public boolean isBytes(MessageField field) {
return isScalarType(field, BYTES);
}
/**
* Indicates whether the given field is of type {@code float} or {@code double}.
* @param field the given field.
* @return {@code true} if the given field is a floating point number, {@code false} otherwise.
*/
public boolean isFloatingPointNumber(MessageField field) {
return isScalarType(field, FLOAT, DOUBLE);
}
/**
* Indicates whether the given field is of type {@code fixed32}, {@code fixed64}, {@code int32}, {@code int64},
* {@code sfixed32}, {@code sfixed64}, {@code sint32}, {@code sint64}, {@code uint32} or {@code uint64}.
* @param field the given field.
* @return {@code true} if the given field is an integer, {@code false} otherwise.
*/
public boolean isInteger(MessageField field) {
return isScalarType(field, FIXED32, FIXED64, INT32, INT64, SFIXED32, SFIXED64, SINT32, SINT64, UINT32, UINT64);
}
/**
* Indicates whether the given field is of type {@code string}.
* @param field the given field.
* @return {@code true} if the given field is of type {@code string}, {@code false} otherwise.
*/
public boolean isString(MessageField field) {
return isScalarType(field, STRING);
}
/**
* Indicates whether the given field is of type {@code fixed32}, {@code fixed64}, {@code uint32} or {@code uint64}.
* @param field the given field.
* @return {@code true} if the given field is an unsigned integer, {@code false} otherwise.
*/
public boolean isUnsignedInteger(MessageField field) {
return isScalarType(field, FIXED32, FIXED64, UINT32, UINT64);
}
private boolean isScalarType(MessageField field, CommonKeyword... scalarNames) {
TypeLink link = field.getType();
if (link instanceof ScalarTypeLink) {
String typeName = ((ScalarTypeLink) link).getTarget().getName();
for (CommonKeyword scalarName : scalarNames) {
if (scalarName.hasValue(typeName)) {
return true;
}
}
}
return false;
}
/**
* Returns the name of the type of the given field.
* @param field the given field.
* @return the name of the type of the given field.
*/
public String typeNameOf(MessageField field) {
ScalarType scalarType = scalarTypeOf(field);
if (scalarType != null) {
return scalarType.getName();
}
ComplexType complexType = typeOf(field);
if (complexType != null) {
return complexType.getName();
}
return null;
}
/**
* Returns the message type of the given field, only if the type of the given field is a message.
* @param field the given field.
* @return the message type of the given field or {@code null} if the type of the given field is not message.
*/
public Message messageTypeOf(MessageField field) {
return fieldType(field, Message.class);
}
/**
* Returns the enum type of the given field, only if the type of the given field is an enum.
* @param field the given field.
* @return the enum type of the given field or {@code null} if the type of the given field is not enum.
*/
public Enum enumTypeOf(MessageField field) {
return fieldType(field, Enum.class);
}
private <T extends ComplexType> T fieldType(MessageField field, Class<T> targetType) {
ComplexType type = typeOf(field);
if (targetType.isInstance(type)) {
return targetType.cast(type);
}
return null;
}
/**
* Returns the type of the given field.
* @param field the given field.
* @return the type of the given field.
*/
public ComplexType typeOf(MessageField field) {
TypeLink link = field.getType();
if (link instanceof ComplexTypeLink) {
return ((ComplexTypeLink) link).getTarget();
}
return null;
}
/**
* Returns the scalar type of the given field, only if the type of the given field is a scalar.
* @param field the given field.
* @return the scalar type of the given field or {@code null} if the type of the given field is not a scalar.
*/
public ScalarType scalarTypeOf(MessageField field) {
TypeLink link = (field).getType();
if (link instanceof ScalarTypeLink) {
return ((ScalarTypeLink) link).getTarget();
}
return null;
}
}