/*
 * Copyright The async-profiler authors
 * SPDX-License-Identifier: Apache-2.0
 */

#include "jfrMetadata.h"


Index Element::_strings;

JfrMetadata JfrMetadata::_root;

JfrMetadata::JfrMetadata() : Element("root") {
    *this
        << (element("metadata")

            << type("boolean", T_BOOLEAN)
            << type("char", T_CHAR)
            << type("float", T_FLOAT)
            << type("double", T_DOUBLE)
            << type("byte", T_BYTE)
            << type("short", T_SHORT)
            << type("int", T_INT)
            << type("long", T_LONG)

            << type("java.lang.String", T_STRING)

            << (type("java.lang.Class", T_CLASS, "Java Class")
                << field("classLoader", T_CLASS_LOADER, "Class Loader", F_CPOOL)
                << field("name", T_SYMBOL, "Name", F_CPOOL)
                << field("package", T_PACKAGE, "Package", F_CPOOL)
                << field("modifiers", T_INT, "Access Modifiers"))

            << (type("java.lang.Thread", T_THREAD, "Thread")
                << field("osName", T_STRING, "OS Thread Name")
                << field("osThreadId", T_LONG, "OS Thread Id")
                << field("javaName", T_STRING, "Java Thread Name")
                << field("javaThreadId", T_LONG, "Java Thread Id"))

            << (type("jdk.types.ClassLoader", T_CLASS_LOADER, "Java Class Loader")
                << field("type", T_CLASS, "Type", F_CPOOL)
                << field("name", T_SYMBOL, "Name", F_CPOOL))

            << (type("jdk.types.FrameType", T_FRAME_TYPE, "Frame type", true)
                << field("description", T_STRING, "Description"))

            << (type("jdk.types.ThreadState", T_THREAD_STATE, "Java Thread State", true)
                << field("name", T_STRING, "Name"))

            << (type("jdk.types.StackTrace", T_STACK_TRACE, "Stacktrace")
                << field("truncated", T_BOOLEAN, "Truncated")
                << field("frames", T_STACK_FRAME, "Stack Frames", F_ARRAY))

            << (type("jdk.types.StackFrame", T_STACK_FRAME)
                << field("method", T_METHOD, "Java Method", F_CPOOL)
                << field("lineNumber", T_INT, "Line Number")
                << field("bytecodeIndex", T_INT, "Bytecode Index")
                << field("type", T_FRAME_TYPE, "Frame Type", F_CPOOL))

            << (type("jdk.types.Method", T_METHOD, "Java Method")
                << field("type", T_CLASS, "Type", F_CPOOL)
                << field("name", T_SYMBOL, "Name", F_CPOOL)
                << field("descriptor", T_SYMBOL, "Descriptor", F_CPOOL)
                << field("modifiers", T_INT, "Access Modifiers")
                << field("hidden", T_BOOLEAN, "Hidden"))

            << (type("jdk.types.VirtualSpace", T_VIRTUAL_SPACE)
                << field("start", T_LONG, "Start Address", F_ADDRESS)
                << field("committedEnd", T_LONG, "Committed End Address", F_ADDRESS)
                << field("committedSize", T_LONG, "Committed Size", F_BYTES)
                << field("reservedEnd", T_LONG, "Reserved End Address", F_ADDRESS)
                << field("reservedSize", T_LONG, "Reserved Size", F_BYTES))

            << (type("jdk.types.Package", T_PACKAGE, "Package")
                << field("name", T_SYMBOL, "Name", F_CPOOL))

            << (type("jdk.types.Symbol", T_SYMBOL, "Symbol", true)
                << field("string", T_STRING, "String"))

            << (type("jdk.types.GCWhen", T_GC_WHEN, "GC When", true)
                << field("when", T_STRING, "When"))

            << (type("profiler.types.LogLevel", T_LOG_LEVEL, "Log Level", true)
                << field("name", T_STRING, "Name"))

            << (type("profiler.types.UserEventType", T_USER_EVENT_TYPE, "User-Defined Event Type", true)
                << field("name", T_STRING, "Name"))

            << (type("jdk.ExecutionSample", T_EXECUTION_SAMPLE, "Method Profiling Sample")
                << category("Java Virtual Machine", "Profiling")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("sampledThread", T_THREAD, "Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("state", T_THREAD_STATE, "Thread State", F_CPOOL))

            << (type("jdk.ObjectAllocationInNewTLAB", T_ALLOC_IN_NEW_TLAB, "Allocation in new TLAB")
                << category("Java Application")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("objectClass", T_CLASS, "Object Class", F_CPOOL)
                << field("allocationSize", T_LONG, "Allocation Size", F_BYTES)
                << field("tlabSize", T_LONG, "TLAB Size", F_BYTES))

            << (type("jdk.ObjectAllocationOutsideTLAB", T_ALLOC_OUTSIDE_TLAB, "Allocation outside TLAB")
                << category("Java Application")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("objectClass", T_CLASS, "Object Class", F_CPOOL)
                << field("allocationSize", T_LONG, "Allocation Size", F_BYTES))

            << (type("jdk.JavaMonitorEnter", T_MONITOR_ENTER, "Java Monitor Blocked")
                << category("Java Application")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("duration", T_LONG, "Duration", F_DURATION_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("monitorClass", T_CLASS, "Monitor Class", F_CPOOL)
                << field("previousOwner", T_THREAD, "Previous Monitor Owner", F_CPOOL)
                << field("address", T_LONG, "Monitor Address", F_ADDRESS))

            << (type("jdk.ThreadPark", T_THREAD_PARK, "Java Thread Park")
                << category("Java Application")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("duration", T_LONG, "Duration", F_DURATION_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("parkedClass", T_CLASS, "Class Parked On", F_CPOOL)
                << field("timeout", T_LONG, "Park Timeout", F_DURATION_NANOS)
                << field("until", T_LONG, "Park Until", F_TIME_MILLIS)
                << field("address", T_LONG, "Address of Object Parked", F_ADDRESS))

            << (type("jdk.CPULoad", T_CPU_LOAD, "CPU Load")
                << category("Operating System", "Processor")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("jvmUser", T_FLOAT, "JVM User", F_PERCENTAGE)
                << field("jvmSystem", T_FLOAT, "JVM System", F_PERCENTAGE)
                << field("machineTotal", T_FLOAT, "Machine Total", F_PERCENTAGE))

            << (type("jdk.ActiveRecording", T_ACTIVE_RECORDING, "Async-profiler Recording")
                << category("Flight Recorder")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("id", T_LONG, "Id")
                << field("name", T_STRING, "Name")
                << field("destination", T_STRING, "Destination")
                << field("maxAge", T_LONG, "Max Age", F_DURATION_MILLIS)
                << field("maxSize", T_LONG, "Max Size", F_BYTES)
                << field("recordingStart", T_LONG, "Start Time", F_TIME_MILLIS)
                << field("recordingDuration", T_LONG, "Recording Duration", F_DURATION_MILLIS))

            << (type("jdk.ActiveSetting", T_ACTIVE_SETTING, "Async-profiler Setting")
                << category("Flight Recorder")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("id", T_LONG, "Event Id")
                << field("name", T_STRING, "Setting Name")
                << field("value", T_STRING, "Setting Value"))

            << (type("jdk.OSInformation", T_OS_INFORMATION, "OS Information")
                << category("Operating System")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("osVersion", T_STRING, "OS Version"))

            << (type("jdk.CPUInformation", T_CPU_INFORMATION, "CPU Information")
                << category("Operating System", "Processor")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("cpu", T_STRING, "Type")
                << field("description", T_STRING, "Description")
                << field("sockets", T_INT, "Sockets", F_UNSIGNED)
                << field("cores", T_INT, "Cores", F_UNSIGNED)
                << field("hwThreads", T_INT, "Hardware Threads", F_UNSIGNED))

            << (type("jdk.JVMInformation", T_JVM_INFORMATION, "JVM Information")
                << category("Java Virtual Machine")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("jvmName", T_STRING, "JVM Name")
                << field("jvmVersion", T_STRING, "JVM Version")
                << field("jvmArguments", T_STRING, "JVM Command Line Arguments")
                << field("jvmFlags", T_STRING, "JVM Settings File Arguments")
                << field("javaArguments", T_STRING, "Java Application Arguments")
                << field("jvmStartTime", T_LONG, "JVM Start Time", F_TIME_MILLIS)
                << field("pid", T_LONG, "Process Identifier"))

            << (type("jdk.InitialSystemProperty", T_INITIAL_SYSTEM_PROPERTY, "Initial System Property")
                << category("Java Virtual Machine")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("key", T_STRING, "Key")
                << field("value", T_STRING, "Value"))

            << (type("jdk.NativeLibrary", T_NATIVE_LIBRARY, "Native Library")
                << category("Java Virtual Machine", "Runtime")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("name", T_STRING, "Name")
                << field("baseAddress", T_LONG, "Base Address", F_ADDRESS)
                << field("topAddress", T_LONG, "Top Address", F_ADDRESS))

            << (type("jdk.GCHeapSummary", T_GC_HEAP_SUMMARY, "Heap Summary")
                << category("Java Virtual Machine", "GC", "Heap")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("gcId", T_INT, "GC Identifier", F_UNSIGNED)
                << field("when", T_GC_WHEN, "When", F_CPOOL)
                << field("heapSpace", T_VIRTUAL_SPACE, "VirtualSpace")
                << field("heapUsed", T_LONG, "Heap Used", F_BYTES))

            << (type("jdk.MethodTrace", T_METHOD_TRACE, "Method Trace")
                << category("Java Virtual Machine", "Method Tracing")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("duration", T_LONG, "Duration", F_DURATION_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("method", T_METHOD, "Method", F_CPOOL))

            << (type("profiler.Log", T_LOG, "Log Message")
                << category("Profiler")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("level", T_LOG_LEVEL, "Level", F_CPOOL)
                << field("message", T_STRING, "Message"))

            << (type("profiler.Window", T_WINDOW, "Profiling Window")
                << category("Profiler")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("duration", T_LONG, "Duration", F_DURATION_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL))

            << (type("profiler.LiveObject", T_LIVE_OBJECT, "Live Object")
                << category("Java Application")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("objectClass", T_CLASS, "Object Class", F_CPOOL)
                << field("allocationSize", T_LONG, "Allocation Size", F_BYTES)
                << field("allocationTime", T_LONG, "Allocation Time", F_TIME_TICKS))

            << (type("profiler.WallClockSample", T_WALL_CLOCK_SAMPLE, "Wall Clock Sample")
                << category("Java Virtual Machine", "Profiling")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("sampledThread", T_THREAD, "Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("state", T_THREAD_STATE, "Thread State", F_CPOOL)
                << field("samples", T_INT, "Samples", F_UNSIGNED))

            << (type("profiler.Malloc", T_MALLOC, "malloc")
                << category("Java Virtual Machine", "Native Memory")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("address", T_LONG, "Address", F_ADDRESS)
                << field("size", T_LONG, "Size", F_BYTES))

            << (type("profiler.Free", T_FREE, "free")
                << category("Java Virtual Machine", "Native Memory")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
                << field("address", T_LONG, "Address", F_ADDRESS))

            << (type("profiler.UserEvent", T_USER_EVENT, "User-Defined Event")
                << category("Profiler")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
                << field("type", T_USER_EVENT_TYPE, "User Event Type", F_CPOOL)
                // Using T_STRING with a Latin-1 string to encode raw bytes as user data.
                // This is not type-correct, but `jfr print` has a NullPointerException
                // when encountering a T_BYTE/F_ARRAY.
                << field("data", T_STRING, "User Data"))

            << (type("profiler.ProcessSample", T_PROCESS_SAMPLE, "Process Stats Sample")
                << category("Operating System", "Process")
                << field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
                << field("pid", T_INT, "Process ID", F_UNSIGNED)
                << field("ppid", T_INT, "Parent Process ID", F_UNSIGNED)
                << field("name", T_STRING, "Process Name")
                << field("cmdLine", T_STRING, "Command Line")
                << field("uid", T_INT, "User ID", F_UNSIGNED)
                << field("state", T_BYTE, "Process State")
                << field("processStartTime", T_LONG, "Process Start Time", F_TIME_MILLIS)
                << field("cpuUser", T_FLOAT, "User CPU Time")
                << field("cpuSystem", T_FLOAT, "System CPU Time")
                << field("cpuPercent", T_FLOAT, "CPU Percentage", F_PERCENTAGE)
                << field("threads", T_INT, "Thread Count", F_UNSIGNED)
                << field("vmSize", T_LONG, "Virtual Memory Size", F_BYTES)
                << field("vmRss", T_LONG, "Resident Memory Size", F_BYTES)
                << field("rssAnon", T_LONG, "Resident anonymous memory", F_BYTES)
                << field("rssFiles", T_LONG, "Resident file mappings", F_BYTES)
                << field("rssShmem", T_LONG, "Resident shared Memory", F_BYTES)
                << field("minorFaults", T_LONG, "Minor Page Faults", F_UNSIGNED)
                << field("majorFaults", T_LONG, "Major Page Faults", F_UNSIGNED)
                << field("ioRead", T_LONG, "I/O Read Bytes", F_BYTES)
                << field("ioWrite", T_LONG, "I/O Write Bytes", F_BYTES))

            << (type("jdk.jfr.Label", T_LABEL, NULL)
                << field("value", T_STRING))

            << (type("jdk.jfr.Category", T_CATEGORY, NULL)
                << field("value", T_STRING, NULL, F_ARRAY))

            << type("jdk.jfr.ContentType", T_CONTENT_TYPE, "Content Type")

            << (type("jdk.jfr.Timestamp", T_TIMESTAMP, "Timestamp")
                << field("value", T_STRING))

            << (type("jdk.jfr.Timespan", T_TIMESPAN, "Timespan")
                << field("value", T_STRING))

            << (type("jdk.jfr.DataAmount", T_DATA_AMOUNT, "Data Amount")
                << field("value", T_STRING))

            << type("jdk.jfr.MemoryAddress", T_MEMORY_ADDRESS, "Memory Address")

            << type("jdk.jfr.Unsigned", T_UNSIGNED, "Unsigned Value")

            << type("jdk.jfr.Percentage", T_PERCENTAGE, "Percentage"))

        << element("region").attribute("locale", "en_US").attribute("gmtOffset", "0");
}
