/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
*/
package org.opensolaris.os.adr;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public abstract class Type {
public enum Source { BASE, COMPLEX, ENUM, ARRAY, FORWARD };
public static class BuiltinType extends Type {
private StdType type_;
public BuiltinType(StdType t) {
super(Source.BASE);
type_ = t;
}
public StdType getType() {
return type_;
}
@Override
public String toString() {
return type_.toString().toLowerCase();
}
}
public abstract static class DefinedType extends Type
implements Definition {
private Interface interface_;
private String name_;
DefinedType(Source s, String name) {
super(s);
name_ = name;
}
public String getName() {
return name_;
}
@Override
public void setInterface(Interface iface) {
interface_ = iface;
}
@Override
public Interface getInterface() {
return interface_;
}
}
public static class ComplexType extends DefinedType {
private List<Field> fields_;
private List<ComplexType> parents_;
private Doc doc_;
public ComplexType(String name, List<Field> fields,
List<ComplexType> parents, Doc doc) {
super(Source.COMPLEX, name);
fields_ = fields;
parents_ = parents;
doc_ = doc;
}
public ComplexType(String name, List<Field> fields,
List<ComplexType> parents) {
this(name, fields, parents, null);
}
public List<Field> getFields() {
return fields_;
}
public List<ComplexType> getParents() {
return parents_;
}
public Doc getDoc() {
return doc_;
}
public List<Field> getAllFields() {
if (parents_ == null)
return fields_;
List<Field> result = new LinkedList<Field>();
for (ComplexType t : parents_)
result.addAll(t.getAllFields());
result.addAll(fields_);
return result;
}
public Field getField(String name) {
if (parents_ != null) {
for (ComplexType t : parents_) {
Field f = t.getField(name);
if (f != null)
return f;
}
}
for (Field f : fields_)
if (f.getName().equals(name))
return f;
return null;
}
@Override
public String toString() {
return "struct " + getName();
}
}
public static class EnumValue {
private String name_;
private int value_;
private Doc doc_;
public EnumValue(String name, int value, Doc doc) {
name_ = name;
value_ = value;
doc_ = doc;
}
public EnumValue(String name, int value) {
this(name, value, null);
}
public String getName() {
return name_;
}
public int getValue() {
return value_;
}
public Doc getDoc() {
return doc_;
}
}
public static class EnumType extends DefinedType {
private List<EnumValue> values_;
private EnumValue fallback_;
private Doc doc_;
public EnumType(String name, List<EnumValue> values, EnumValue fallback,
Doc doc) {
super(Source.ENUM, name);
values_ = values;
fallback_ = fallback;
doc_ = doc;
}
public EnumType(String name, List<EnumValue> values,
EnumValue fallback) {
this(name, values, fallback, null);
}
public List<EnumValue> getValues() {
return values_;
}
public EnumValue getFallback() {
return fallback_;
}
public Doc getDoc() {
return doc_;
}
@Override
public String toString() {
return "enum " + getName();
}
}
public static class ArrayType extends Type implements HasType {
Type type_;
public ArrayType(Type type) {
super(Source.ARRAY);
type_ = type;
if (type.getSource() == Type.Source.FORWARD)
((Type.ForwardType)type).addReference(this);
}
@Override
public void setType(Type type) {
type_ = type;
}
@Override
public Type getType() {
return (type_);
}
@Override
public boolean isOptional() {
return false;
}
@Override
public String toString() {
return type_.toString() + "[]";
}
}
public static class ForwardType extends DefinedType {
List<HasType> references_;
public ForwardType(String name) {
super(Source.FORWARD, name);
references_ = new LinkedList<HasType>();
}
public void addReference(HasType ref) {
references_.add(ref);
}
public Collection<HasType> getReferences() {
return references_;
}
@Override
public String toString() {
return "forward reference to \"" + getName() + "\"";
}
}
public static final Map<StdType, BuiltinType> BUILTINS;
public static final Map<BuiltinType, ArrayType> BUILTIN_ARRAYS;
static {
Map<StdType, BuiltinType> builtins =
new HashMap<StdType, BuiltinType>();
Map<BuiltinType, ArrayType> builtin_arrays =
new HashMap<BuiltinType, ArrayType>();
for (StdType t : StdType.values()) {
BuiltinType bi = new BuiltinType(t);
builtins.put(t, bi);
if (t != StdType.VOID)
builtin_arrays.put(bi, new ArrayType(bi));
}
BUILTINS = Collections.unmodifiableMap(builtins);
BUILTIN_ARRAYS = Collections.unmodifiableMap(builtin_arrays);
}
public static Type getType(StdType type) {
return (BUILTINS.get(type));
}
public static Type getArrayType(BuiltinType type) {
return (BUILTIN_ARRAYS.get(type));
}
public static Type getArrayType(Type type) {
if (type instanceof BuiltinType)
return getArrayType((BuiltinType)type);
return new ArrayType(type);
}
/*
* Instance variables/methods.
*/
private Source source_;
private Map<String, Object> decorations_ = new HashMap<String, Object>();
protected Type(Source source) {
source_ = source;
}
public Source getSource() {
return (source_);
}
public void setAuxData(String key, Object value) {
decorations_.put(key, value);
}
public Object getAuxData(String key) {
return decorations_.get(key);
}
@Override
public abstract String toString();
}