<commit_before>package org.inferred.freebuilder.processor;

import static org.inferred.freebuilder.processor.util.ModelUtils.findAnnotationMirror;
import static org.inferred.freebuilder.processor.util.ModelUtils.findProperty;

import com.google.common.annotations.GwtCompatible;

import org.inferred.freebuilder.processor.Datatype.Visibility;
import org.inferred.freebuilder.processor.util.Block;
import org.inferred.freebuilder.processor.util.Excerpt;
import org.inferred.freebuilder.processor.util.Excerpts;
import org.inferred.freebuilder.processor.util.QualifiedName;
import org.inferred.freebuilder.processor.util.SourceBuilder;
import org.inferred.freebuilder.processor.util.TypeMirrorExcerpt;
import org.inferred.freebuilder.processor.util.Variable;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.TypeElement;

class GwtSupport {

  private static final QualifiedName CUSTOM_FIELD_SERIALIZER =
      QualifiedName.of("com.google.gwt.user.client.rpc", "CustomFieldSerializer");
  private static final QualifiedName SERIALIZATION_EXCEPTION =
      QualifiedName.of("com.google.gwt.user.client.rpc", "SerializationException");
  private static final QualifiedName SERIALIZATION_STREAM_READER =
      QualifiedName.of("com.google.gwt.user.client.rpc", "SerializationStreamReader");
  private static final QualifiedName SERIALIZATION_STREAM_WRITER =
      QualifiedName.of("com.google.gwt.user.client.rpc", "SerializationStreamWriter");

  public static Datatype.Builder gwtMetadata(
      TypeElement type,
      Datatype datatype,
      Map<Property, PropertyCodeGenerator> generatorsByProperty) {
    Datatype.Builder extraMetadata = new Datatype.Builder();
    Optional<AnnotationMirror> annotation = findAnnotationMirror(type, GwtCompatible.class);
    if (annotation.isPresent()) {
      extraMetadata.addGeneratedBuilderAnnotations(Excerpts.add("@%s%n", GwtCompatible.class));
      Optional<AnnotationValue> serializable = findProperty(annotation.get(), "serializable");
      if (serializable.isPresent() && serializable.get().getValue().equals(Boolean.TRUE)) {
        // Due to a bug in GWT's handling of nested types, we have to declare Value as package
        // scoped so Value_CustomFieldSerializer can access it.
        extraMetadata.setValueTypeVisibility(Visibility.PACKAGE);
        extraMetadata.addValueTypeAnnotations(Excerpts.add(
            "@%s(serializable = true)%n", GwtCompatible.class));
        extraMetadata.addNestedClasses(new CustomValueSerializer(datatype, generatorsByProperty));
        extraMetadata.addNestedClasses(new GwtWhitelist(datatype, generatorsByProperty.keySet()));
        QualifiedName builderName = datatype.getGeneratedBuilder().getQualifiedName();
        extraMetadata.addVisibleNestedTypes(
            builderName.nestedType("Value_CustomFieldSerializer"),
            builderName.nestedType("GwtWhitelist"));
      }
    }
    return extraMetadata;
  }

  private static final class CustomValueSerializer extends Excerpt {

    private final Datatype datatype;
    private final Map<Property, PropertyCodeGenerator> generatorsByProperty;

    private CustomValueSerializer(
        Datatype datatype,
        Map<Property, PropertyCodeGenerator> generatorsByProperty) {
      this.datatype = datatype;
      this.generatorsByProperty = generatorsByProperty;
    }

    @Override
    public void addTo(SourceBuilder code) {
      code.addLine("")
          .addLine("@%s", GwtCompatible.class);
      if (datatype.getType().isParameterized()) {
        code.addLine("@%s(\"unchecked\")", SuppressWarnings.class);
      }
      code.addLine("public static class Value_CustomFieldSerializer")
          .addLine("    extends %s<%s> {", CUSTOM_FIELD_SERIALIZER, datatype.getValueType())
          .addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public void deserializeInstance(%s reader, %s instance) { }",
              SERIALIZATION_STREAM_READER, datatype.getValueType())
          .addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public boolean hasCustomInstantiateInstance() {")
          .addLine("    return true;")
          .addLine("  }");
      addInstantiateInstance(code);
      addSerializeInstance(code);
      code.addLine("")
          .addLine("  private static final Value_CustomFieldSerializer INSTANCE ="
              + " new Value_CustomFieldSerializer();")
          .addLine("")
          .addLine("  public static void deserialize(%s reader, %s instance) {",
              SERIALIZATION_STREAM_READER, datatype.getValueType())
          .addLine("    INSTANCE.deserializeInstance(reader, instance);")
          .addLine("  }")
          .addLine("")
          .addLine("  public static %s instantiate(%s reader)",
              datatype.getValueType(), SERIALIZATION_STREAM_READER)
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION)
          .addLine("    return INSTANCE.instantiateInstance(reader);")
          .addLine("  }")
          .addLine("")
          .addLine("  public static void serialize(%s writer, %s instance)",
              SERIALIZATION_STREAM_WRITER, datatype.getValueType())
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION)
          .addLine("    INSTANCE.serializeInstance(writer, instance);")
          .addLine("  }")
          .addLine("}");
    }

    private void addInstantiateInstance(SourceBuilder code) {
      code.addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public %s instantiateInstance(%s reader)",
              datatype.getValueType(), SERIALIZATION_STREAM_READER)
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION);
      Block body = Block.methodBody(code, "reader");
      Excerpt builder = body.declare(
          datatype.getBuilder(), "builder", Excerpts.add("new %s()", datatype.getBuilder()));
      for (Property property : generatorsByProperty.keySet()) {
        TypeMirrorExcerpt propertyType = new TypeMirrorExcerpt(property.getType());
        if (property.getType().getKind().isPrimitive()) {
          Excerpt value = body.declare(
              propertyType,
              property.getName(),
              Excerpts.add("reader.read%s()", withInitialCapital(property.getType())));
          generatorsByProperty.get(property).addSetFromResult(body, builder, value);
        } else if (String.class.getName().equals(property.getType().toString())) {
          Excerpt value = body.declare(
              propertyType,
              property.getName(),
              Excerpts.add("reader.readString()"));
          generatorsByProperty.get(property).addSetFromResult(body, builder, value);
        } else {
          Variable temporary = new Variable(property.getName());
          body.addLine("    try {");
          if (!property.isFullyCheckedCast()) {
            body.addLine("      @SuppressWarnings(\"unchecked\")");
          }
          body.addLine("      %1$s %2$s = (%1$s) reader.readObject();", propertyType, temporary);
          generatorsByProperty.get(property).addSetFromResult(body, builder, temporary);
          body.addLine("    } catch (%s e) {", ClassCastException.class)
              .addLine("      throw new %s(", SERIALIZATION_EXCEPTION)
              .addLine("          \"Wrong type for property '%s'\", e);", property.getName())
              .addLine("    }");
        }
      }
      body.addLine("    return (%s) %s.build();", datatype.getValueType(), builder);
      code.add(body)
          .addLine("  }");
    }

    private void addSerializeInstance(SourceBuilder code) {
      code.addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public void serializeInstance(%s writer, %s instance)",
              SERIALIZATION_STREAM_WRITER, datatype.getValueType())
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION);
      for (Property property : generatorsByProperty.keySet()) {
        if (property.getType().getKind().isPrimitive()) {<commit_msg>Replace legacy use of Block.declare in GwtSupport<commit_after>package org.inferred.freebuilder.processor;

import static org.inferred.freebuilder.processor.util.ModelUtils.findAnnotationMirror;
import static org.inferred.freebuilder.processor.util.ModelUtils.findProperty;

import com.google.common.annotations.GwtCompatible;

import org.inferred.freebuilder.processor.Datatype.Visibility;
import org.inferred.freebuilder.processor.util.Block;
import org.inferred.freebuilder.processor.util.Excerpt;
import org.inferred.freebuilder.processor.util.Excerpts;
import org.inferred.freebuilder.processor.util.QualifiedName;
import org.inferred.freebuilder.processor.util.SourceBuilder;
import org.inferred.freebuilder.processor.util.TypeMirrorExcerpt;
import org.inferred.freebuilder.processor.util.Variable;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.TypeElement;

class GwtSupport {

  private static final QualifiedName CUSTOM_FIELD_SERIALIZER =
      QualifiedName.of("com.google.gwt.user.client.rpc", "CustomFieldSerializer");
  private static final QualifiedName SERIALIZATION_EXCEPTION =
      QualifiedName.of("com.google.gwt.user.client.rpc", "SerializationException");
  private static final QualifiedName SERIALIZATION_STREAM_READER =
      QualifiedName.of("com.google.gwt.user.client.rpc", "SerializationStreamReader");
  private static final QualifiedName SERIALIZATION_STREAM_WRITER =
      QualifiedName.of("com.google.gwt.user.client.rpc", "SerializationStreamWriter");

  public static Datatype.Builder gwtMetadata(
      TypeElement type,
      Datatype datatype,
      Map<Property, PropertyCodeGenerator> generatorsByProperty) {
    Datatype.Builder extraMetadata = new Datatype.Builder();
    Optional<AnnotationMirror> annotation = findAnnotationMirror(type, GwtCompatible.class);
    if (annotation.isPresent()) {
      extraMetadata.addGeneratedBuilderAnnotations(Excerpts.add("@%s%n", GwtCompatible.class));
      Optional<AnnotationValue> serializable = findProperty(annotation.get(), "serializable");
      if (serializable.isPresent() && serializable.get().getValue().equals(Boolean.TRUE)) {
        // Due to a bug in GWT's handling of nested types, we have to declare Value as package
        // scoped so Value_CustomFieldSerializer can access it.
        extraMetadata.setValueTypeVisibility(Visibility.PACKAGE);
        extraMetadata.addValueTypeAnnotations(Excerpts.add(
            "@%s(serializable = true)%n", GwtCompatible.class));
        extraMetadata.addNestedClasses(new CustomValueSerializer(datatype, generatorsByProperty));
        extraMetadata.addNestedClasses(new GwtWhitelist(datatype, generatorsByProperty.keySet()));
        QualifiedName builderName = datatype.getGeneratedBuilder().getQualifiedName();
        extraMetadata.addVisibleNestedTypes(
            builderName.nestedType("Value_CustomFieldSerializer"),
            builderName.nestedType("GwtWhitelist"));
      }
    }
    return extraMetadata;
  }

  private static final class CustomValueSerializer extends Excerpt {

    private final Datatype datatype;
    private final Map<Property, PropertyCodeGenerator> generatorsByProperty;

    private CustomValueSerializer(
        Datatype datatype,
        Map<Property, PropertyCodeGenerator> generatorsByProperty) {
      this.datatype = datatype;
      this.generatorsByProperty = generatorsByProperty;
    }

    @Override
    public void addTo(SourceBuilder code) {
      code.addLine("")
          .addLine("@%s", GwtCompatible.class);
      if (datatype.getType().isParameterized()) {
        code.addLine("@%s(\"unchecked\")", SuppressWarnings.class);
      }
      code.addLine("public static class Value_CustomFieldSerializer")
          .addLine("    extends %s<%s> {", CUSTOM_FIELD_SERIALIZER, datatype.getValueType())
          .addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public void deserializeInstance(%s reader, %s instance) { }",
              SERIALIZATION_STREAM_READER, datatype.getValueType())
          .addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public boolean hasCustomInstantiateInstance() {")
          .addLine("    return true;")
          .addLine("  }");
      addInstantiateInstance(code);
      addSerializeInstance(code);
      code.addLine("")
          .addLine("  private static final Value_CustomFieldSerializer INSTANCE ="
              + " new Value_CustomFieldSerializer();")
          .addLine("")
          .addLine("  public static void deserialize(%s reader, %s instance) {",
              SERIALIZATION_STREAM_READER, datatype.getValueType())
          .addLine("    INSTANCE.deserializeInstance(reader, instance);")
          .addLine("  }")
          .addLine("")
          .addLine("  public static %s instantiate(%s reader)",
              datatype.getValueType(), SERIALIZATION_STREAM_READER)
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION)
          .addLine("    return INSTANCE.instantiateInstance(reader);")
          .addLine("  }")
          .addLine("")
          .addLine("  public static void serialize(%s writer, %s instance)",
              SERIALIZATION_STREAM_WRITER, datatype.getValueType())
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION)
          .addLine("    INSTANCE.serializeInstance(writer, instance);")
          .addLine("  }")
          .addLine("}");
    }

    private void addInstantiateInstance(SourceBuilder code) {
      code.addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public %s instantiateInstance(%s reader)",
              datatype.getValueType(), SERIALIZATION_STREAM_READER)
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION);
      Block body = Block.methodBody(code, "reader");
      Variable builder = new Variable("builder");
      body.addLine("    %1$s %2$s = new %1$s();", datatype.getBuilder(), builder);
      for (Property property : generatorsByProperty.keySet()) {
        TypeMirrorExcerpt propertyType = new TypeMirrorExcerpt(property.getType());
        Variable temporary = new Variable(property.getName());
        if (property.getType().getKind().isPrimitive()) {
          body.addLine("    %s %s = reader.read%s();",
              propertyType, temporary, withInitialCapital(property.getType()));
          generatorsByProperty.get(property).addSetFromResult(body, builder, temporary);
        } else if (String.class.getName().equals(property.getType().toString())) {
          body.addLine("    %s %s = reader.readString();", propertyType, temporary);
          generatorsByProperty.get(property).addSetFromResult(body, builder, temporary);
        } else {
          body.addLine("    try {");
          if (!property.isFullyCheckedCast()) {
            body.addLine("      @SuppressWarnings(\"unchecked\")");
          }
          body.addLine("      %1$s %2$s = (%1$s) reader.readObject();", propertyType, temporary);
          generatorsByProperty.get(property).addSetFromResult(body, builder, temporary);
          body.addLine("    } catch (%s e) {", ClassCastException.class)
              .addLine("      throw new %s(", SERIALIZATION_EXCEPTION)
              .addLine("          \"Wrong type for property '%s'\", e);", property.getName())
              .addLine("    }");
        }
      }
      body.addLine("    return (%s) %s.build();", datatype.getValueType(), builder);
      code.add(body)
          .addLine("  }");
    }

    private void addSerializeInstance(SourceBuilder code) {
      code.addLine("")
          .addLine("  @%s", Override.class)
          .addLine("  public void serializeInstance(%s writer, %s instance)",
              SERIALIZATION_STREAM_WRITER, datatype.getValueType())
          .addLine("      throws %s {", SERIALIZATION_EXCEPTION);
      for (Property property : generatorsByProperty.keySet()) {
        if (property.getType().getKind().isPrimitive()) {
{'fraction_non_alphanumeric': 0.12179368887248569, 'fraction_numerical': 0.0005536076766931168, 'mean_word_length': 3.252681140465603, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5935843', 'n_tokens_mistral': 4537, 'n_tokens_neox': 4477, 'n_words': 837}