<commit_before>package org.smoothbuild.lang.object.db;

import static org.smoothbuild.lang.base.type.Types.isGenericTypeName;
import static org.smoothbuild.lang.object.base.Messages.ERROR;
import static org.smoothbuild.lang.object.base.Messages.INFO;
import static org.smoothbuild.lang.object.base.Messages.SEVERITY;
import static org.smoothbuild.lang.object.base.Messages.TEXT;
import static org.smoothbuild.lang.object.base.Messages.WARNING;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.smoothbuild.lang.object.base.ArrayBuilder;
import org.smoothbuild.lang.object.base.Blob;
import org.smoothbuild.lang.object.base.BlobBuilder;
import org.smoothbuild.lang.object.base.Bool;
import org.smoothbuild.lang.object.base.SObject;
import org.smoothbuild.lang.object.base.SString;
import org.smoothbuild.lang.object.base.Struct;
import org.smoothbuild.lang.object.base.StructBuilder;
import org.smoothbuild.lang.object.type.ArrayType;
import org.smoothbuild.lang.object.type.ConcreteArrayType;
import org.smoothbuild.lang.object.type.ConcreteType;
import org.smoothbuild.lang.object.type.Field;
import org.smoothbuild.lang.object.type.GenericArrayType;
import org.smoothbuild.lang.object.type.GenericType;
import org.smoothbuild.lang.object.type.StringType;
import org.smoothbuild.lang.object.type.StructType;
import org.smoothbuild.lang.object.type.Type;
import org.smoothbuild.lang.object.type.TypeNames;
import org.smoothbuild.util.io.DataWriter;

/**
 * This class is thread-safe.
 * Builders returned by xxxBuilder() methods are not thread-safe.
 */
@Singleton
public class ObjectFactory {
  private final ObjectDb objectDb;
  private final ConcurrentHashMap<String, ConcreteType> cache;

  @Inject
  public ObjectFactory(ObjectDb objectDb) {
    this.objectDb = objectDb;
    this.cache = createInitializedCache(objectDb);
  }

  private static ConcurrentHashMap<String, ConcreteType> createInitializedCache(ObjectDb objectDb) {
    ConcurrentHashMap<String, ConcreteType> map = new ConcurrentHashMap<>();
    putType(map, objectDb.blobType());
    putType(map, objectDb.boolType());
    putType(map, objectDb.nothingType());
    putType(map, objectDb.stringType());
    return map;
  }

  private static void putType(Map<String, ConcreteType> map, ConcreteType type) {
    map.put(type.name(), type);
  }

  public ArrayBuilder arrayBuilder(ConcreteType elementType) {
    return objectDb.arrayBuilder(elementType);
  }

  public Blob blob(DataWriter dataWriter) throws IOException {
    try (BlobBuilder builder = blobBuilder()) {
      dataWriter.writeTo(builder.sink());
      return builder.build();
    }
  }

  public BlobBuilder blobBuilder() {
    return objectDb.blobBuilder();
  }

  public Bool bool(boolean value) {
    return objectDb.bool(value);
  }

  public Struct file(SString path, Blob content) {
    return structBuilder(fileType())
        .set("content", content)
        .set("path", path)
        .build();
  }

  public SString string(String string) {
    return objectDb.string(string);
  }

  public StructBuilder structBuilder(StructType type) {
    return objectDb.structBuilder(type);
  }

  public ArrayType arrayType(Type elementType) {
    if (elementType.isGeneric()) {
      return arrayType((GenericType) elementType);
    } else {
      return arrayType((ConcreteType) elementType);
    }
  }

  public ConcreteArrayType arrayType(ConcreteType elementType) {
    return objectDb.arrayType(elementType);
  }

  public GenericArrayType arrayType(GenericType elementType) {
    return new GenericArrayType(elementType);
  }

  public ConcreteType blobType() {
    return objectDb.blobType();
  }

  public ConcreteType boolType() {
    return objectDb.boolType();
  }

  public StructType fileType() {
    return (StructType) getType(TypeNames.FILE);
  }

  public StructType messageType() {
    return (StructType) getType(TypeNames.MESSAGE);
  }

  public ConcreteType nothingType() {
    return objectDb.nothingType();
  }

  public StringType stringType() {
    return objectDb.stringType();
  }

  public StructType structType(String name, Iterable<Field> fields) {
    StructType type = objectDb.structType(name, fields);
    ConcreteType previousValue = cache.putIfAbsent(name, type);<commit_msg>improved ObjectFactory method return types to be more specific<commit_after>package org.smoothbuild.lang.object.db;

import static org.smoothbuild.lang.base.type.Types.isGenericTypeName;
import static org.smoothbuild.lang.object.base.Messages.ERROR;
import static org.smoothbuild.lang.object.base.Messages.INFO;
import static org.smoothbuild.lang.object.base.Messages.SEVERITY;
import static org.smoothbuild.lang.object.base.Messages.TEXT;
import static org.smoothbuild.lang.object.base.Messages.WARNING;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.smoothbuild.lang.object.base.ArrayBuilder;
import org.smoothbuild.lang.object.base.Blob;
import org.smoothbuild.lang.object.base.BlobBuilder;
import org.smoothbuild.lang.object.base.Bool;
import org.smoothbuild.lang.object.base.SObject;
import org.smoothbuild.lang.object.base.SString;
import org.smoothbuild.lang.object.base.Struct;
import org.smoothbuild.lang.object.base.StructBuilder;
import org.smoothbuild.lang.object.type.ArrayType;
import org.smoothbuild.lang.object.type.BlobType;
import org.smoothbuild.lang.object.type.BoolType;
import org.smoothbuild.lang.object.type.ConcreteArrayType;
import org.smoothbuild.lang.object.type.ConcreteType;
import org.smoothbuild.lang.object.type.Field;
import org.smoothbuild.lang.object.type.GenericArrayType;
import org.smoothbuild.lang.object.type.GenericType;
import org.smoothbuild.lang.object.type.NothingType;
import org.smoothbuild.lang.object.type.StringType;
import org.smoothbuild.lang.object.type.StructType;
import org.smoothbuild.lang.object.type.Type;
import org.smoothbuild.lang.object.type.TypeNames;
import org.smoothbuild.util.io.DataWriter;

/**
 * This class is thread-safe.
 * Builders returned by xxxBuilder() methods are not thread-safe.
 */
@Singleton
public class ObjectFactory {
  private final ObjectDb objectDb;
  private final ConcurrentHashMap<String, ConcreteType> cache;

  @Inject
  public ObjectFactory(ObjectDb objectDb) {
    this.objectDb = objectDb;
    this.cache = createInitializedCache(objectDb);
  }

  private static ConcurrentHashMap<String, ConcreteType> createInitializedCache(ObjectDb objectDb) {
    ConcurrentHashMap<String, ConcreteType> map = new ConcurrentHashMap<>();
    putType(map, objectDb.blobType());
    putType(map, objectDb.boolType());
    putType(map, objectDb.nothingType());
    putType(map, objectDb.stringType());
    return map;
  }

  private static void putType(Map<String, ConcreteType> map, ConcreteType type) {
    map.put(type.name(), type);
  }

  public ArrayBuilder arrayBuilder(ConcreteType elementType) {
    return objectDb.arrayBuilder(elementType);
  }

  public Blob blob(DataWriter dataWriter) throws IOException {
    try (BlobBuilder builder = blobBuilder()) {
      dataWriter.writeTo(builder.sink());
      return builder.build();
    }
  }

  public BlobBuilder blobBuilder() {
    return objectDb.blobBuilder();
  }

  public Bool bool(boolean value) {
    return objectDb.bool(value);
  }

  public Struct file(SString path, Blob content) {
    return structBuilder(fileType())
        .set("content", content)
        .set("path", path)
        .build();
  }

  public SString string(String string) {
    return objectDb.string(string);
  }

  public StructBuilder structBuilder(StructType type) {
    return objectDb.structBuilder(type);
  }

  public ArrayType arrayType(Type elementType) {
    if (elementType.isGeneric()) {
      return arrayType((GenericType) elementType);
    } else {
      return arrayType((ConcreteType) elementType);
    }
  }

  public ConcreteArrayType arrayType(ConcreteType elementType) {
    return objectDb.arrayType(elementType);
  }

  public GenericArrayType arrayType(GenericType elementType) {
    return new GenericArrayType(elementType);
  }

  public BlobType blobType() {
    return objectDb.blobType();
  }

  public BoolType boolType() {
    return objectDb.boolType();
  }

  public StructType fileType() {
    return (StructType) getType(TypeNames.FILE);
  }

  public StructType messageType() {
    return (StructType) getType(TypeNames.MESSAGE);
  }

  public NothingType nothingType() {
    return objectDb.nothingType();
  }

  public StringType stringType() {
    return objectDb.stringType();
  }

  public StructType structType(String name, Iterable<Field> fields) {
    StructType type = objectDb.structType(name, fields);
    ConcreteType previousValue = cache.putIfAbsent(name, type);
{'fraction_non_alphanumeric': 0.10693868400403542, 'fraction_numerical': 0.0, 'mean_word_length': 4.653992395437262, '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': '827951', 'n_tokens_mistral': 2716, 'n_tokens_neox': 2628, 'n_words': 531}