@Override
  protected void init(Type type, Class<?> objectClass,
                      ObjectInspectorFactory.ObjectInspectorOptions options) {
    this.type = type;

    verifyObjectClassType(objectClass);
    this.objectClass = objectClass;
    final Field fieldMetaData;

    try {
      fieldMetaData = objectClass.getDeclaredField(FIELD_METADATA_MAP);
      assert(Map.class.isAssignableFrom(fieldMetaData.getType()));
      fieldMetaData.setAccessible(true);
    } catch (NoSuchFieldException e) {
      throw new RuntimeException("Unable to find field metadata for thrift union field " , e);
    }

    try {
      final Map<? extends TFieldIdEnum, FieldMetaData> fieldMap = (Map<? extends TFieldIdEnum, FieldMetaData>) fieldMetaData.get(null);
      synchronized (this) {
        fields = new ArrayList<StandardStructObjectInspector.MyField>(fieldMap.size());
        this.ois = new ArrayList<ObjectInspector>();
        for(Map.Entry<? extends TFieldIdEnum, FieldMetaData> metadata : fieldMap.entrySet()) {
          int fieldId = metadata.getKey().getThriftFieldId();
          String fieldName = metadata.getValue().fieldName;
          final Type fieldType = ThriftObjectInspectorUtils.getFieldType(objectClass, fieldName);
          final ObjectInspector reflectionObjectInspector = ObjectInspectorFactory.getReflectionObjectInspector(fieldType, options, false);
          fields.add(new StandardStructObjectInspector.MyField(fieldId, fieldName, reflectionObjectInspector));
          this.ois.add(reflectionObjectInspector);
          this.notifyAll();
        }
        inited = true;
      }
    } catch (IllegalAccessException e) {
      throw new RuntimeException("Unable to find field metadata for thrift union field ", e);
    }
  }
This method is only intended to be used by Utilities class in this package.
The reason that this method is not recursive by itself is because we want
to allow recursive types.
serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ThriftUnionObjectInspector.java