<commit_before>//
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file NOSA-1.3-JPF at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//

package gov.nasa.jpf.util.json;

import gov.nasa.jpf.JPFException;
import gov.nasa.jpf.jvm.ChoiceGenerator;
import gov.nasa.jpf.jvm.ClassInfo;
import gov.nasa.jpf.jvm.ElementInfo;
import gov.nasa.jpf.jvm.FieldInfo;
import gov.nasa.jpf.jvm.Fields;
import gov.nasa.jpf.jvm.MJIEnv;
import gov.nasa.jpf.jvm.SystemState;
import gov.nasa.jpf.util.ObjectConverter;
import java.util.HashMap;
import java.util.Set;

/**
 * Object parsed from JSON document.
 * @author <NAME>
 */
public class JSONObject{

  private HashMap<String, Value> keyValues = new HashMap<String, Value>();
  private HashMap<String, CGCall> cgCalls = new HashMap<String, CGCall>();

  void addValue(String key, Value value) {
    if (keyValues.containsKey(key)) {
      throw new JPFException("Attempt to add two nodes with the same key in JSON object");
    }

    keyValues.put(key, value);
  }

  /**
   * Get value read from JSON document with specified key.
   * @param key - value's key.
   * @return read value.
   */
  public Value getValue(String key) {
    return keyValues.get(key);
  }

  public String[] getValuesKeys() {
    Set<String> valuesKeys = keyValues.keySet();
    String[] result = new String[keyValues.size()];

    valuesKeys.toArray(result);
    return result;
  }

  public void addCGCall(String key, CGCall cgCall) {
    if (cgCalls.containsKey(key)) {
      throw new JPFException("Attempt to add two CG with the same key in JSON object");
    }

    cgCalls.put(key, cgCall);
  }

  public CGCall getCGCall(String key) {
    return cgCalls.get(key);
  }

  public String[] getCGCallsKeys() {
    Set<String> cgKeys = cgCalls.keySet();
    String[] result = new String[cgKeys.size()];

    cgKeys.toArray(result);
    return result;
  }


  //--- the fillers
  public int fillObject(MJIEnv env, String typeName, ChoiceGenerator[] CGs, String prefix) {

    int newObjRef = env.newObject(typeName);
    ElementInfo ei = env.getHeap().get(newObjRef);

    if (ei == null) {
      throw new JPFException("No such class " + typeName);
    }

    ClassInfo ci = ei.getClassInfo();

    // Fill all fields for this class until it has a super class
    while (ci != null) {
      FieldInfo[] fields = ci.getDeclaredInstanceFields();

      for (FieldInfo fi : fields) {
        String fieldName = fi.getName();
        Value val = getValue(fieldName);
        CGCall cgCall = getCGCall(fieldName);

        // If a value was defined in JSON document
        if (val != null) {
          fillFromValue(fi, ei, val, env, CGs, prefix);
        }
        // Value of this field should be taken from CG
        else if (cgCall != null) {
          String cgId = prefix + fieldName;
          ChoiceGenerator cg = getCGByID(CGs, cgId);          
          assert cg != null : "Expected CG with id " + cgId;
          
          Object cgResult = cg.getNextChoice();

          if (!fi.isReference()) {
            convertPrimititve(ei, fi, cgResult);
          }
          else {
            int newFieldRef = ObjectConverter.JPFObjectFromJavaObject(env, cgResult);
            ei.setReferenceField(fi, newFieldRef);
          }
        }
      }

      ci = ci.getSuperClass();
    }

    return newObjRef;
  }

  private void fillFromValue(FieldInfo fi, ElementInfo ei, Value val, MJIEnv env, ChoiceGenerator[] CGs, String prefix) {
    String fieldName = fi.getName();
    // Handle primitive types
    if (!fi.isReference()) {
      fillPrimitive(ei, fi, val);<commit_msg>createObjectFromJSON fixed. Now it write warnings to log if no value was specified for a field.<commit_after>//
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file NOSA-1.3-JPF at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//

package gov.nasa.jpf.util.json;

import gov.nasa.jpf.JPF;
import gov.nasa.jpf.JPFException;
import gov.nasa.jpf.jvm.ChoiceGenerator;
import gov.nasa.jpf.jvm.ClassInfo;
import gov.nasa.jpf.jvm.ElementInfo;
import gov.nasa.jpf.jvm.FieldInfo;
import gov.nasa.jpf.jvm.Fields;
import gov.nasa.jpf.jvm.MJIEnv;
import gov.nasa.jpf.util.JPFLogger;
import gov.nasa.jpf.util.ObjectConverter;
import java.util.HashMap;
import java.util.Set;

/**
 * Object parsed from JSON document.
 * @author <NAME>
 */
public class JSONObject{

  private static final JPFLogger logger = JPF.getLogger("gov.nasa.jpf.util.json.JSONObject");

  private HashMap<String, Value> keyValues = new HashMap<String, Value>();
  private HashMap<String, CGCall> cgCalls = new HashMap<String, CGCall>();

  void addValue(String key, Value value) {
    if (keyValues.containsKey(key)) {
      throw new JPFException("Attempt to add two nodes with the same key in JSON object");
    }

    keyValues.put(key, value);
  }

  /**
   * Get value read from JSON document with specified key.
   * @param key - value's key.
   * @return read value.
   */
  public Value getValue(String key) {
    return keyValues.get(key);
  }

  public String[] getValuesKeys() {
    Set<String> valuesKeys = keyValues.keySet();
    String[] result = new String[keyValues.size()];

    valuesKeys.toArray(result);
    return result;
  }

  public void addCGCall(String key, CGCall cgCall) {
    if (cgCalls.containsKey(key)) {
      throw new JPFException("Attempt to add two CG with the same key in JSON object");
    }

    cgCalls.put(key, cgCall);
  }

  public CGCall getCGCall(String key) {
    return cgCalls.get(key);
  }

  public String[] getCGCallsKeys() {
    Set<String> cgKeys = cgCalls.keySet();
    String[] result = new String[cgKeys.size()];

    cgKeys.toArray(result);
    return result;
  }


  //--- the fillers
  public int fillObject(MJIEnv env, String typeName, ChoiceGenerator[] CGs, String prefix) {

    int newObjRef = env.newObject(typeName);
    ElementInfo ei = env.getHeap().get(newObjRef);

    if (ei == null) {
      throw new JPFException("No such class " + typeName);
    }

    ClassInfo ci = ei.getClassInfo();

    // Fill all fields for this class until it has a super class
    while (ci != null) {
      FieldInfo[] fields = ci.getDeclaredInstanceFields();

      for (FieldInfo fi : fields) {
        String fieldName = fi.getName();
        Value val = getValue(fieldName);
        CGCall cgCall = getCGCall(fieldName);

        // If a value was defined in JSON document
        if (val != null) {
          fillFromValue(fi, ei, val, env, CGs, prefix);
        }
        // Value of this field should be taken from CG
        else if (cgCall != null) {
          String cgId = prefix + fieldName;
          ChoiceGenerator cg = getCGByID(CGs, cgId);          
          assert cg != null : "Expected CG with id " + cgId;
          
          Object cgResult = cg.getNextChoice();

          if (!fi.isReference()) {
            convertPrimititve(ei, fi, cgResult);
          }
          else {
            int newFieldRef = ObjectConverter.JPFObjectFromJavaObject(env, cgResult);
            ei.setReferenceField(fi, newFieldRef);
          }
        }
        else {
          logger.warning("Value for field " + fi.getFullName() + " isn't specified");
        }
      }

      ci = ci.getSuperClass();
    }

    return newObjRef;
  }

  private void fillFromValue(FieldInfo fi, ElementInfo ei, Value val, MJIEnv env, ChoiceGenerator[] CGs, String prefix) {
    String fieldName = fi.getName();
    // Handle primitive types
    if (!fi.isReference()) {
      fillPrimitive(ei, fi, val);
{'fraction_non_alphanumeric': 0.1063922942206655, 'fraction_numerical': 0.0017513134851138354, 'mean_word_length': 2.9180960548885078, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, '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': '7142744', 'n_tokens_mistral': 2905, 'n_tokens_neox': 2808, 'n_words': 895}