Translating EnumDefinition(s)

Enums are mapped to a Java wrapper, so that we're ensure typing during calls. The translation scheme is:

Let's take an enum Status {Off, On}. The translation will produce a Status java class, with the following structure.

Example 5-1. Enum Wrapper

import java.util.Hashtable;

final public class Status {
  int value_;

  public Status(int value) {
    value_ = value;
  }

  public int getValue() {
    return value_;
  }

  public int hashCode() {
    return value_;
  }

  public boolean equals(Object other) {
    return (other instanceof Status)
      && (((Status) other).value_ == value_);
  }

  static private Hashtable theInternedExtras = null;
  static private Status theSacrificialOne = new Status(0);
  static public synchronized Status intern(int value) {
    if (value < theInterned.length)
      return theInterned[value];
    theSacrificialOne.value_ = value;
    if (theInternedExtras == null)
      theInternedExtras = new Hashtable();
    Status already  = (Status) theInternedExtras.get(theSacrificialOne);
    if (already == null) {
      already = new Status(value);
      theInternedExtras.put(already, already);
    }
    return already;
  }

  static private Status[] theInterned = {
   new Status(0),
   new Status(1),
  };

  public final static int _Off = 0;
  public final static Status Off = theInterned[0];
  public final static int _On = 1;
  public final static Status On = theInterned[1];
}

A C function setLight(Status s) would be translated to a method setLight(Status s). This java method is generated to automatically unwrap the Status Java object, and then pass the integer constant to the native code. Using the "Status" wrapper is quite easy, either through the static instances which wrap the int values, or through the integer value, with the constructor and accessor (it might be useful in switch() blocks, for instance).

Every enumerated type comes with a means to intern elements of that type. Interning is the process by which, for a given integer value, only one corresponding object will ever be created, allowing for memory efficiency and the ability to compare objects using the == operator and having that be equivalent to using the Object.equals() method. The interning mechanism is set up so that an enumeration may gain new elements dynamically. This isn't needed by every enumerated type, but there are some which do require this behavior (in particular, GtkType).

This translation closely mimics the one found in the CORBA IDL/Java mapping.