content: package com.alibaba.fastjson2.writer;
  
  import com.alibaba.fastjson2.JSONB;
  import com.alibaba.fastjson2.JSONException;
  import com.alibaba.fastjson2.JSONWriter;
  import com.alibaba.fastjson2.util.Fnv;
  import com.alibaba.fastjson2.util.TypeUtils;
  
  import java.lang.reflect.*;
  
  final class ObjectWriterImplEnum<E extends Enum<E>>
          extends ObjectWriterPrimitiveImpl {
      final Member valueField;
  
      final Class defineClass;
      final Class enumType;
      final long features;
  
      byte[] typeNameJSONB;
      long typeNameHash;
  
      final Enum[] enumConstants;
      final String[] names;
      final long[] hashCodes;
  
      byte[][] jsonbNames;
      final String[] annotationNames;
  
      public ObjectWriterImplEnum(
              Class defineClass,
              Class enumType,
              Member valueField,
              String[] annotationNames,
              long features
      ) {
          this.defineClass = defineClass;
          this.enumType = enumType;
          this.features = features;
          this.valueField = valueField;
  
          if (valueField instanceof AccessibleObject) {
              try {
                  ((AccessibleObject) valueField).setAccessible(true);
              } catch (Throwable ignored) {
                  // ignored
              }
          }
  
          this.enumConstants = (Enum[]) enumType.getEnumConstants();
          this.names = new String[enumConstants.length];
          this.hashCodes = new long[enumConstants.length];
          for (int i = 0; i < enumConstants.length; i++) {
              String name = enumConstants[i].name();
              this.names[i] = name;
              hashCodes[i] = Fnv.hashCode64(name);
          }
          this.annotationNames = annotationNames;
      }
  
      @Override
      public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
          if (jsonWriter.isWriteTypeInfo(object, fieldType, features)) {
              if (typeNameJSONB == null) {
                  String typeName = TypeUtils.getTypeName(enumType);
                  typeNameJSONB
                          = JSONB.toBytes(
                          typeName);
                  typeNameHash = Fnv.hashCode64(typeName);
              }
              jsonWriter.writeTypeName(typeNameJSONB, typeNameHash);
          }
  
          Enum e = (Enum) object;
          if (jsonWriter.isEnabled(JSONWriter.Feature.WriteEnumUsingToString)) {
              jsonWriter.writeString(e.toString());
          } else {
              if (jsonbNames == null) {
                  jsonbNames = new byte[this.names.length][];
              }
  
              int ordinal = e.ordinal();
              byte[] jsonbName = this.jsonbNames[ordinal];
              if (jsonbName == null) {
                  jsonbName = JSONB.toBytes(this.names[ordinal]);
                  this.jsonbNames[ordinal] = jsonbName;
              }
              jsonWriter.writeRaw(jsonbName);
          }
      }
  
      @Override
      public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
          Enum e = (Enum) object;
          if (e == null) {
              jsonWriter.writeNull();
              return;
          }
  
          if (valueField != null) {
              Object fieldValue;
              try {
                  if (valueField instanceof Field) {
                      fieldValue = ((Field) valueField).get(object);
                  } else {
                      fieldValue = ((Method) valueField).invoke(object);
                  }
                  if (fieldValue != object) {
                      jsonWriter.writeAny(fieldValue);
                      return;
                  }
              } catch (Exception error) {
                  throw new JSONException("getEnumValue error", error);
              }
          }
  
          long features2 = jsonWriter.getFeatures(features | this.features);
  
          if ((features2 & JSONWriter.Feature.WriteEnumUsingToString.mask) != 0) {
              jsonWriter.writeString(e.toString());
              return;
          }
  
          if ((features2 & JSONWriter.Feature.WriteEnumUsingOrdinal.mask) != 0) {
              jsonWriter.writeInt32(e.ordinal());
              return;
          }
  
          String enumName = null;
          if (annotationNames != null) {
              int ordinal = e.ordinal();
              if (ordinal < annotationNames.length) {
                  enumName = annotationNames[ordinal];
              }
          }
          if (enumName == null) {
              enumName = e.name();
          }
          jsonWriter.writeString(enumName);
      }
  }
  