<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.codegen;

import java.io.FileWriter;
import java.io.File;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.stream.Collectors;

/**
 * This class autogenerates C++ code for the C++ config, based on a CNode tree given.
 */
public class CppClassBuilder implements ClassBuilder {

    private final CNode root;
    private final NormalizedDefinition nd;
    private final File rootDir;
    private final String relativePathUnderRoot;
    private static final Map<String, String> vectorTypeDefs;
    static {
        Map<String, String> map = new HashMap<String, String>();
        map.put("bool", "BoolVector");
        map.put("int32_t", "IntVector");
        map.put("int64_t", "LongVector");
        map.put("double", "DoubleVector");
        map.put("vespalib::string", "StringVector");
        vectorTypeDefs = Collections.unmodifiableMap(map);
    }
    private static final Map<String, String> mapTypeDefs;
    static {
        Map<String, String> map = new HashMap<>();
        map.put("bool", "BoolMap");
        map.put("int32_t", "IntMap");
        map.put("int64_t", "LongMap");
        map.put("double", "DoubleMap");
        map.put("vespalib::string", "StringMap");
        mapTypeDefs = Collections.unmodifiableMap(map);
    }
    private static final Map<String, String> slimeTypeMap;
    static {
        Map<String, String> map = new HashMap<String, String>();
        map.put("bool", "Bool");
        map.put("int", "Long");
        map.put("long", "Long");
        map.put("double", "Double");
        map.put("string", "String");
        map.put("enum", "String");
        map.put("file", "String");
        map.put("reference", "String");
        slimeTypeMap = Collections.unmodifiableMap(map);
    }

    public CppClassBuilder(CNode root, NormalizedDefinition nd, File rootDir, String relativePathUnderRoot) {
        this.root = root;
        this.nd = nd;
        this.rootDir = rootDir;
        this.relativePathUnderRoot = relativePathUnderRoot;
    }

    public void createConfigClasses() {
        generateConfig(root, nd);
    }

    String readFile(File f) throws IOException {
        if (!f.isFile()) return null;
        StringBuilder sb = new StringBuilder();
        try (BufferedReader sr = new BufferedReader(new FileReader(f))) {
            while (true) {
                String line = sr.readLine();
                if (line == null) break;
                sb.append(line).append("\n");
            }
            return sb.toString();
        }
    }

    void writeFile(File f, String content) throws IOException {
        FileWriter fw = new FileWriter(f);
        fw.write(content);
        fw.close();
    }

    void generateConfig(CNode root, NormalizedDefinition nd) {
        try{
            StringWriter headerWriter = new StringWriter();
            StringWriter bodyWriter = new StringWriter();
            writeHeaderFile(headerWriter, root);
            writeBodyFile(bodyWriter, root, relativePathUnderRoot, nd);

            String newHeader = headerWriter.toString();
            String newBody = bodyWriter.toString();

            File headerFile = new File(rootDir, relativePathUnderRoot + "/" + getFileName(root, "h"));
            File bodyFile = new File(rootDir, relativePathUnderRoot + "/" + getFileName(root, "cpp"));

            String oldHeader = readFile(headerFile);
            String oldBody = readFile(bodyFile);

            if (oldHeader == null || !oldHeader.equals(newHeader)) {
                writeFile(headerFile, newHeader);
            }
            if (oldBody == null || !oldBody.equals(newBody)) {
                writeFile(bodyFile, newBody);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    String getFileName(CNode node, String extension) {
        return "config-" + node.getName() + "." + extension;
    }

    static String removeDashesAndUpperCaseAllFirstChars(String source, boolean capitalizeFirst) {
        // Create upper case chars after each dash
        String parts[] = source.split("[-_]");
        StringBuilder sb = new StringBuilder();
        for (String s : parts) {<commit_msg>If you have decided that you need to build the config, you must do so and also write it, evevn if it was identical.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.codegen;

import java.io.FileWriter;
import java.io.File;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.stream.Collectors;

/**
 * This class autogenerates C++ code for the C++ config, based on a CNode tree given.
 */
public class CppClassBuilder implements ClassBuilder {

    private final CNode root;
    private final NormalizedDefinition nd;
    private final File rootDir;
    private final String relativePathUnderRoot;
    private static final Map<String, String> vectorTypeDefs;
    static {
        Map<String, String> map = new HashMap<String, String>();
        map.put("bool", "BoolVector");
        map.put("int32_t", "IntVector");
        map.put("int64_t", "LongVector");
        map.put("double", "DoubleVector");
        map.put("vespalib::string", "StringVector");
        vectorTypeDefs = Collections.unmodifiableMap(map);
    }
    private static final Map<String, String> mapTypeDefs;
    static {
        Map<String, String> map = new HashMap<>();
        map.put("bool", "BoolMap");
        map.put("int32_t", "IntMap");
        map.put("int64_t", "LongMap");
        map.put("double", "DoubleMap");
        map.put("vespalib::string", "StringMap");
        mapTypeDefs = Collections.unmodifiableMap(map);
    }
    private static final Map<String, String> slimeTypeMap;
    static {
        Map<String, String> map = new HashMap<String, String>();
        map.put("bool", "Bool");
        map.put("int", "Long");
        map.put("long", "Long");
        map.put("double", "Double");
        map.put("string", "String");
        map.put("enum", "String");
        map.put("file", "String");
        map.put("reference", "String");
        slimeTypeMap = Collections.unmodifiableMap(map);
    }

    public CppClassBuilder(CNode root, NormalizedDefinition nd, File rootDir, String relativePathUnderRoot) {
        this.root = root;
        this.nd = nd;
        this.rootDir = rootDir;
        this.relativePathUnderRoot = relativePathUnderRoot;
    }

    public void createConfigClasses() {
        generateConfig(root, nd);
    }

    String readFile(File f) throws IOException {
        if (!f.isFile()) return null;
        StringBuilder sb = new StringBuilder();
        try (BufferedReader sr = new BufferedReader(new FileReader(f))) {
            while (true) {
                String line = sr.readLine();
                if (line == null) break;
                sb.append(line).append("\n");
            }
            return sb.toString();
        }
    }

    void writeFile(File f, String content) throws IOException {
        FileWriter fw = new FileWriter(f);
        fw.write(content);
        fw.close();
    }

    void generateConfig(CNode root, NormalizedDefinition nd) {
        try{
            StringWriter headerWriter = new StringWriter();
            StringWriter bodyWriter = new StringWriter();
            writeHeaderFile(headerWriter, root);
            writeBodyFile(bodyWriter, root, relativePathUnderRoot, nd);

            String newHeader = headerWriter.toString();
            String newBody = bodyWriter.toString();

            File headerFile = new File(rootDir, relativePathUnderRoot + "/" + getFileName(root, "h"));
            File bodyFile = new File(rootDir, relativePathUnderRoot + "/" + getFileName(root, "cpp"));

            writeFile(headerFile, newHeader);
            writeFile(bodyFile, newBody);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    String getFileName(CNode node, String extension) {
        return "config-" + node.getName() + "." + extension;
    }

    static String removeDashesAndUpperCaseAllFirstChars(String source, boolean capitalizeFirst) {
        // Create upper case chars after each dash
        String parts[] = source.split("[-_]");
        StringBuilder sb = new StringBuilder();
        for (String s : parts) {
{'fraction_non_alphanumeric': 0.1203589455973079, 'fraction_numerical': 0.0031407739764441954, 'mean_word_length': 2.6751854905193735, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, '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': '6203518', 'n_tokens_mistral': 2490, 'n_tokens_neox': 2418, 'n_words': 659}