content: package com.alibaba.fastjson.serializer;
  
  import com.alibaba.fastjson.JSON;
  import com.alibaba.fastjson2.JSONWriter;
  import com.alibaba.fastjson2.filter.LabelFilter;
  import com.alibaba.fastjson2.filter.PropertyPreFilter;
  
  import java.io.IOException;
  import java.io.Writer;
  import java.nio.charset.Charset;
  import java.util.ArrayList;
  import java.util.List;
  
  public class SerializeWriter
          implements Cloneable {
      SerializeConfig config;
      final JSONWriter raw;
  
      final ListWrapper<PropertyFilter> propertyFilters;
      final ListWrapper<ValueFilter> valueFilters;
      final ListWrapper<NameFilter> nameFilters;
      final ListWrapper<BeforeFilter> beforeFilters;
      final ListWrapper<AfterFilter> afterFilters;
  
      public SerializeWriter() {
          this(JSONWriter.of());
      }
  
      public SerializeWriter(SerializerFeature... features) {
          this(
                  JSONWriter.of(
                          JSON.createWriteContext(
                                  SerializeConfig.global,
                                  JSON.DEFAULT_PARSER_FEATURE,
                                  features
                          )
                  )
          );
      }
  
      public SerializeWriter(SerializeConfig config, SerializerFeature... features) {
          this(
                  JSONWriter.of(
                          JSON.createWriteContext(
                                  config,
                                  JSON.DEFAULT_PARSER_FEATURE,
                                  features
                          )
                  )
          );
          this.config = config;
      }
  
      public SerializeWriter(JSONWriter raw) {
          this.raw = raw;
          this.propertyFilters = new ListWrapper<>();
          this.valueFilters = new ListWrapper<>();
          this.nameFilters = new ListWrapper<>();
          this.beforeFilters = new ListWrapper<>();
          this.afterFilters = new ListWrapper<>();
      }
  
      public void writeNull() {
          this.raw.writeNull();
      }
  
      public void writeNull(SerializerFeature feature) {
          this.raw.writeNull();
      }
  
      public void writeString(String text) {
          this.raw.writeString(text);
      }
  
      public void write(String text) {
          this.raw.writeRaw(text);
      }
  
      public List<PropertyFilter> getPropertyFilters() {
          return propertyFilters;
      }
  
      public List<ValueFilter> getValueFilters() {
          return valueFilters;
      }
  
      public List<NameFilter> getNameFilters() {
          return nameFilters;
      }
  
      public List<BeforeFilter> getBeforeFilters() {
          return beforeFilters;
      }
  
      public List<AfterFilter> getAfterFilters() {
          return afterFilters;
      }
  
      class ListWrapper<T>
              extends ArrayList<T> {
          @Override
          public boolean add(T filter) {
              JSONWriter.Context context = raw.getContext();
  
              if (filter instanceof PropertyFilter) {
                  context.setPropertyFilter((PropertyFilter) filter);
              }
  
              if (filter instanceof ValueFilter) {
                  context.setValueFilter((ValueFilter) filter);
              }
  
              if (filter instanceof NameFilter) {
                  context.setNameFilter((NameFilter) filter);
              }
  
              if (filter instanceof PropertyPreFilter) {
                  context.setPropertyPreFilter((PropertyPreFilter) filter);
              }
  
              if (filter instanceof BeforeFilter) {
                  context.setBeforeFilter((BeforeFilter) filter);
              }
  
              if (filter instanceof AfterFilter) {
                  context.setAfterFilter((AfterFilter) filter);
              }
  
              if (filter instanceof LabelFilter) {
                  context.setLabelFilter((LabelFilter) filter);
              }
  
              return super.add(filter);
          }
      }
  
      public void write(int c) {
          raw.writeRaw((char) c);
      }
  
      public void write(char c) {
          raw.writeRaw(c);
      }
  
      public void writeInt(int i) {
          raw.writeInt32(i);
      }
  
      public void writeLong(long i) {
          raw.writeInt64(i);
      }
  
      public void writeFieldName(String key) {
          raw.writeName(key);
      }
  
      @Override
      public String toString() {
          return raw.toString();
      }
  
      public byte[] toBytes(Charset charset) {
          return raw.getBytes(charset);
      }
  
      public byte[] toBytes(String charsetName) {
          return raw.getBytes(Charset.forName(charsetName));
      }
  
      public void close() {
          raw.close();
      }
  
      public void writeTo(Writer out) throws IOException {
          raw.flushTo(out);
      }
  
      public boolean isEnabled(SerializerFeature feature) {
          JSONWriter.Feature rawFeature = null;
          switch (feature) {
              case BeanToArray:
                  rawFeature = JSONWriter.Feature.BeanToArray;
                  break;
              case WriteMapNullValue:
                  rawFeature = JSONWriter.Feature.WriteMapNullValue;
                  break;
              case WriteEnumUsingToString:
                  rawFeature = JSONWriter.Feature.WriteEnumUsingToString;
                  break;
              case WriteEnumUsingName:
                  rawFeature = JSONWriter.Feature.WriteEnumsUsingName;
                  break;
              case WriteNullListAsEmpty:
                  rawFeature = JSONWriter.Feature.WriteNullListAsEmpty;
                  break;
              case WriteNullStringAsEmpty:
                  rawFeature = JSONWriter.Feature.WriteNullStringAsEmpty;
                  break;
              case WriteNullNumberAsZero:
                  rawFeature = JSONWriter.Feature.WriteNullNumberAsZero;
                  break;
              case WriteNullBooleanAsFalse:
                  rawFeature = JSONWriter.Feature.WriteNullBooleanAsFalse;
                  break;
              case WriteClassName:
                  rawFeature = JSONWriter.Feature.WriteClassName;
                  break;
              case NotWriteRootClassName:
                  rawFeature = JSONWriter.Feature.NotWriteRootClassName;
                  break;
              case WriteNonStringKeyAsString:
                  rawFeature = JSONWriter.Feature.WriteNonStringKeyAsString;
                  break;
              case NotWriteDefaultValue:
                  rawFeature = JSONWriter.Feature.NotWriteDefaultValue;
                  break;
              case BrowserCompatible:
                  rawFeature = JSONWriter.Feature.BrowserCompatible;
                  break;
              case BrowserSecure:
                  rawFeature = JSONWriter.Feature.BrowserSecure;
                  break;
              case IgnoreNonFieldGetter:
                  rawFeature = JSONWriter.Feature.IgnoreNonFieldGetter;
                  break;
              case WriteNonStringValueAsString:
                  rawFeature = JSONWriter.Feature.WriteNonStringValueAsString;
                  break;
              case IgnoreErrorGetter:
                  rawFeature = JSONWriter.Feature.IgnoreErrorGetter;
                  break;
              case WriteBigDecimalAsPlain:
                  rawFeature = JSONWriter.Feature.WriteBigDecimalAsPlain;
                  break;
              default:
                  break;
          }
  
          if (rawFeature != null) {
              return raw.isEnabled(rawFeature);
          }
  
          return false;
      }
  
      public SerializeWriter append(char c) {
          raw.writeRaw(c);
          return this;
      }
  
      public JSONWriter getJSONWriter() {
          return raw;
      }
  
      public SerializeWriter append(CharSequence csq) {
          String s = (csq == null ? "null" : csq.toString());
          raw.writeRaw(s);
          return this;
      }
  
      public SerializeWriter append(CharSequence csq, int start, int end) {
          String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
          raw.writeRaw(s);
          return this;
      }
  }
  