usr/src/java/adr/org/opensolaris/os/adr/Type.java
author devjani.ray@oracle.com <devjani.ray@oracle.com>
Fri, 06 May 2011 14:55:38 -0400
changeset 699 34ec90cc612c
parent 681 e3ebf98ba2fd
child 709 6d87dfa365c0
permissions -rw-r--r--
adrgen5 - documentation generator

/*
 * 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();
}