/*****************************************************************************\
 *  parsers.c - Slurm data parsers
 *****************************************************************************
 *  Copyright (C) SchedMD LLC.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include "src/common/data.h"
#include "src/common/log.h"
#include "src/common/read_config.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#include "alloc.h"
#include "api.h"
#include "events.h"
#include "openapi.h"
#include "parsers.h"
#include "parsing.h"
#include "slurmdb_helpers.h"

#define MAGIC_FOREACH_LIST_FLAG 0xa1d4acd2
#define MAGIC_FOREACH_LIST 0xaefa2af3
#define MAGIC_FOREACH_NT_ARRAY 0xaba1be2b
#define MAGIC_FOREACH_PARSE_MARRAY 0xa081be2b

typedef struct {
	int magic;
	ssize_t index;
	args_t *args;
	const parser_t *const parser;
	list_t *list;
	data_t *dlist;
	data_t *parent_path;
} foreach_list_t;

typedef struct {
	int magic; /* MAGIC_FOREACH_LIST_FLAG */
	args_t *args;
	const parser_t *const parser;
	void *dst; /* already has offset applied */
	data_t *parent_path;
	ssize_t index;
	uint64_t set;
} foreach_flag_parser_args_t;

typedef struct {
	int magic; /* MAGIC_FOREACH_NT_ARRAY */
	void **array; /* array of pointers to objects */
	void *sarray; /* array of objects */
	int index;
	const parser_t *const parser;
	const parser_t *const array_parser;
	args_t *args;
	data_t *parent_path;
} foreach_nt_array_t;

typedef struct {
	int magic; /* MAGIC_FOREACH_PARSE_MARRAY */
	args_t *args;
	const parser_t *const array;
	data_t *parent_path;
	data_t *path;
} parse_marray_args_t;

static void _set_flag_bit(const parser_t *const parser, void *dst,
			  const flag_bit_t *bit, bool matched, const char *path,
			  data_t *src)
{
	/* C allows compiler to choose a size for the enum */
	if (parser->size == sizeof(uint64_t)) {
		uint64_t *flags = dst;
		if (matched)
			*flags |= bit->mask & bit->value;
		else
			*flags &= ~bit->mask | (bit->mask & ~bit->value);
	} else if (parser->size == sizeof(uint32_t)) {
		uint32_t *flags = dst;
		if (matched)
			*flags |= bit->mask & bit->value;
		else
			*flags &= ~bit->mask | (bit->mask & ~bit->value);
	} else if (parser->size == sizeof(uint16_t)) {
		uint16_t *flags = dst;
		if (matched)
			*flags |= bit->mask & bit->value;
		else
			*flags &= ~bit->mask | (bit->mask & ~bit->value);
	} else if (parser->size == sizeof(uint8_t)) {
		uint8_t *flags = dst;
		if (matched)
			*flags |= bit->mask & bit->value;
		else
			*flags &= ~bit->mask | (bit->mask & ~bit->value);
	} else {
		fatal_abort("%s: unexpected enum size: %zu",
			    __func__, parser->size);
	}
}

static void _set_flag_bit_equal(const parser_t *const parser, void *dst,
				const flag_bit_t *bit, bool matched,
				const char *path, data_t *src)
{
	/* C allows compiler to choose a size for the enum
	 *
	 * If the comparison is all or nothing, then clear all the masked bits
	 * if it doesn't match which means parser order matters with these.
	 */
	if (parser->size == sizeof(uint64_t)) {
		uint64_t *flags = dst;
		if (matched)
			*flags = (*flags & ~bit->mask) |
				 (bit->mask & bit->value);
		else
			*flags &= ~bit->mask;
	} else if (parser->size == sizeof(uint32_t)) {
		uint32_t *flags = dst;
		if (matched)
			*flags = (*flags & ~bit->mask) |
				 (bit->mask & bit->value);
		else
			*flags &= ~bit->mask;
	} else if (parser->size == sizeof(uint16_t)) {
		uint16_t *flags = dst;
		if (matched)
			*flags = (*flags & ~bit->mask) |
				 (bit->mask & bit->value);
		else
			*flags &= ~bit->mask;
	} else if (parser->size == sizeof(uint8_t)) {
		uint8_t *flags = dst;
		if (matched)
			*flags = (*flags & ~bit->mask) |
				 (bit->mask & bit->value);
		else
			*flags &= ~bit->mask;
	} else {
		fatal_abort("%s: unexpected enum size: %zu",
			    __func__, parser->size);
	}
}

static char *_flag_parent_path(char **path_ptr,
			       foreach_flag_parser_args_t *args)
{
	data_t *ppath;

	if (*path_ptr)
		return *path_ptr;

	if (is_fast_mode(args->args))
		return NULL;

	ppath = clone_source_path_index(args->parent_path, args->index);
	set_source_path(path_ptr, args->args, ppath);
	FREE_NULL_DATA(ppath);

	return *path_ptr;
}

static data_for_each_cmd_t _foreach_flag_parser(data_t *src, void *arg)
{
	foreach_flag_parser_args_t *args = arg;
	void *dst = args->dst;
	const parser_t *const parser = args->parser;
	char *path = NULL;
	bool matched_any = false;
	data_for_each_cmd_t rc = DATA_FOR_EACH_CONT;

	xassert(args->magic == MAGIC_FOREACH_LIST_FLAG);
	xassert(args->args->magic == MAGIC_ARGS);
	xassert(parser->magic == MAGIC_PARSER);

	path = _flag_parent_path(&path, args);

	if (data_convert_type(src, DATA_TYPE_STRING) != DATA_TYPE_STRING) {
		on_warn(PARSING, parser->type, args->args, path,
			__func__, "Ignoring unexpected field of type %s",
			data_get_type_string(src));
		goto cleanup;
	}

	for (int8_t i = 0; (i < parser->flag_bit_array_count); i++) {
		const flag_bit_t *bit = &parser->flag_bit_array[i];
		bool matched = !xstrcasecmp(data_get_string(src), bit->name);

		if (matched)
			matched_any = true;

		if (bit->type == FLAG_BIT_TYPE_BIT) {
			uint64_t value = (bit->mask & bit->value);

			if (matched || (~args->set & value) == value)
				_set_flag_bit(parser, dst, bit, matched, path, src);
			args->set |= value;
		} else if (bit->type == FLAG_BIT_TYPE_EQUAL) {
			if (matched || ((~args->set & bit->mask) == bit->mask))
				_set_flag_bit_equal(parser, dst, bit, matched,
						    path, src);
			args->set |= bit->mask;
		} else if (bit->type == FLAG_BIT_TYPE_REMOVED) {
			if (matched)
				on_warn(PARSING, parser->type, args->args, path,
					__func__,
					"Ignoring deprecated flag: %s",
					bit->name);
		} else
			fatal_abort("%s: invalid bit_flag_t", __func__);

	}

	if (!matched_any)
		on_error(PARSING, parser->type, args->args,
			 ESLURM_DATA_FLAGS_INVALID, path, __func__,
			 "Unknown flag \"%s\"", data_get_string(src));

cleanup:
	xfree(path);
	args->index++;
	return rc;
}

static int _parse_flag(void *dst, const parser_t *const parser, data_t *src,
		       args_t *args, data_t *parent_path)
{
	int rc = SLURM_SUCCESS;
	char *path = NULL;
	foreach_flag_parser_args_t fargs = {
		.magic = MAGIC_FOREACH_LIST_FLAG,
		.args = args,
		.parser = parser,
		.dst = dst,
		.parent_path = parent_path,
	};

	xassert(args->magic == MAGIC_ARGS);
	xassert(parser->magic == MAGIC_PARSER);
	xassert(parser->ptr_offset == NO_VAL);
	xassert(parser->model == PARSER_MODEL_FLAG_ARRAY);

	if (data_get_type(src) == DATA_TYPE_STRING) {
		/* List item may just be a single flag */
		if (_foreach_flag_parser(src, &fargs) != DATA_FOR_EACH_CONT) {
			rc = on_error(PARSING, parser->type, args,
				      ESLURM_DATA_FLAGS_INVALID,
				      set_source_path(&path, args, parent_path),
				      __func__,
				      "Parsing single flag \"%s\" failed",
				      data_get_string(src));

			goto cleanup;
		}
	} else if (data_get_type(src) != DATA_TYPE_LIST) {
		rc = on_error(PARSING, parser->type, args,
			      ESLURM_DATA_FLAGS_INVALID_TYPE,
			      set_source_path(&path, args, parent_path),
			      __func__, "Expected a List but found a %s",
			      data_get_type_string(src));

		goto cleanup;
	/*
	 * Flags need special handling as they are always a LIST with a
	 * matching string value. This requires that each possible flag
	 * must be searched for in the list to know if it is there or
	 * not.
	 */
	} else if (data_list_for_each(src, _foreach_flag_parser, &fargs) < 0) {
		rc = on_error(PARSING, parser->type, args,
			      ESLURM_DATA_FLAGS_INVALID,
			      set_source_path(&path, args, parent_path),
			      __func__, "Parsing flags failed");
		goto cleanup;
	}

cleanup:
	xfree(path);
	return rc;
}

static data_for_each_cmd_t _foreach_parse_list(data_t *src, void *arg)
{
	int rc;
	foreach_list_t *args = arg;
	const parser_t *const parser = args->parser;
	const parser_t *const lparser = find_parser_by_type(parser->list_type);
	void *obj = NULL;
	data_t *ppath = NULL;

	xassert(args->magic == MAGIC_FOREACH_LIST);
	check_parser(parser);
	check_parser(lparser);
	xassert(!args->dlist); /* only for dumping */
	xassert((args->index > 0) || (args->index == -1));

	if (args->index < 0)
		args->index = 0;

	if (!is_fast_mode(args->args)) {
		data_t *ppath_last;

		ppath = data_copy(NULL, args->parent_path);
		ppath_last = data_get_list_last(ppath);

		/* Use jq style array zero based array notation */
		data_set_string_fmt(ppath_last, "%s[%zu]",
				    data_get_string(ppath_last), args->index);
	}

	if ((rc = parse(&obj, NO_VAL, lparser, src, args->args, ppath))) {
		FREE_NULL_DATA(ppath);
		return DATA_FOR_EACH_FAIL;
	}

	args->index++;
	list_append(args->list, obj);

	FREE_NULL_DATA(ppath);
	return DATA_FOR_EACH_CONT;
}

static int _parse_list(const parser_t *const parser, void *dst, data_t *src,
		       args_t *args, data_t *parent_path)
{
	int rc = SLURM_SUCCESS;
	char *path = NULL;
	list_t **list_ptr = dst;
	foreach_list_t list_args = {
		.magic = MAGIC_FOREACH_LIST,
		.dlist = NULL,
		.args = args,
		.parser = parser,
		.parent_path = parent_path,
		.index = -1,
	};

	xassert(!*list_ptr || (list_count(*list_ptr) >= 0));
	xassert(args->magic == MAGIC_ARGS);
	check_parser(parser);

	SWAP(*list_ptr, list_args.list);

	log_flag(DATA, "%s: BEGIN: list parsing %s{%s(0x%"PRIxPTR")} to List 0x%"PRIxPTR" via parser %s(0x%"PRIxPTR")",
		__func__, set_source_path(&path, args, parent_path),
		data_get_type_string(src), (uintptr_t) src,
		(uintptr_t) dst, parser->type_string, (uintptr_t) parser
	);

	if (!list_args.list) {
		const parser_t *const lparser =
			find_parser_by_type(parser->list_type);
		if (lparser->free)
			list_args.list = list_create((ListDelF) lparser->free);
		else
			list_args.list = list_create(xfree_ptr);
	}

	xassert(list_count(list_args.list) >= 0);

	if (data_get_type(src) == DATA_TYPE_LIST) {
		if (data_list_for_each(src, _foreach_parse_list,
				       &list_args) < 0)
			rc = ESLURM_REST_FAIL_PARSING;
	} else if (data_convert_type(src, DATA_TYPE_STRING) ==
		   DATA_TYPE_STRING) {
		/* Assume List is just a single entry */
		if (_foreach_parse_list(src, &list_args) != DATA_FOR_EACH_CONT)
			rc = ESLURM_REST_FAIL_PARSING;
	} else {
		rc = on_error(PARSING, parser->type, args,
			      ESLURM_DATA_EXPECTED_LIST,
			      set_source_path(&path, args, parent_path),
			      __func__, "Expected List but found a %s",
			      data_get_type_string(src));
	}

	if (!rc)
		SWAP(*list_ptr, list_args.list);
	else
		FREE_NULL_LIST(list_args.list);

	log_flag(DATA, "%s: END: list parsing %s{%s(0x%"PRIxPTR")} to List 0x%"PRIxPTR" via parser %s(0x%"PRIxPTR") rc[%d]:%s",
		__func__, path, data_get_type_string(src),
		(uintptr_t) src, (uintptr_t) dst, parser->type_string,
		(uintptr_t) parser, rc, slurm_strerror(rc)
	);

	xfree(path);
	return rc;
}

static int _parse_pointer(const parser_t *const parser, void *dst, data_t *src,
			  args_t *args, data_t *parent_path)
{
	int rc;
	void **ptr = dst;
	const parser_t *const pt = find_parser_by_type(parser->pointer_type);
	bool is_empty_dict = (pt->obj_openapi == OPENAPI_FORMAT_OBJECT) &&
			     (data_get_type(src) == DATA_TYPE_DICT) &&
			     !data_get_dict_length(src);
	bool is_empty_list = (pt->obj_openapi == OPENAPI_FORMAT_ARRAY) &&
			     (data_get_type(src) == DATA_TYPE_LIST) &&
			     !data_get_list_length(src);

	xassert(!*ptr);
	*ptr = alloc_parser_obj(parser);

	if (is_empty_dict || is_empty_list) {
		/*
		 * Detect work around for OpenAPI clients being unable to handle
		 * a null in place of a object/array by placing an empty
		 * dict/array. Place the default allocated object pointer but
+                * skip attempting to parse.
		 */
		return SLURM_SUCCESS;
	}

	if ((rc = parse(*ptr, NO_VAL, pt, src, args, parent_path))) {
		log_flag(DATA, "%s object at 0x%"PRIxPTR" freed due to parser error: %s",
			 pt->obj_type_string, (uintptr_t) ptr,
			 slurm_strerror(rc));
		free_parser_obj(parser, *ptr);
		*ptr = NULL;
	}

	return rc;
}

static data_for_each_cmd_t _foreach_array_entry(data_t *src, void *arg)
{
	int rc;
	foreach_nt_array_t *args = arg;
	void *obj = NULL;
	data_t *ppath = NULL;
	const parser_t *const parser = args->parser;
	const parser_t *const array_parser = args->array_parser;

	xassert(args->magic == MAGIC_FOREACH_NT_ARRAY);
	xassert((args->index > 0) || (args->index == -1));

	if (args->index < 0)
		args->index = 0;

	if (!is_fast_mode(args->args)) {
		data_t *ppath_last;

		ppath = data_copy(NULL, args->parent_path);
		ppath_last = data_get_list_last(ppath);

		/* Use jq style array zero based array notation */
		data_set_string_fmt(ppath_last, "%s[%d]",
				    data_get_string(ppath_last), args->index);
	}

	if (array_parser->model == PARSER_MODEL_NT_PTR_ARRAY)
		obj = alloc_parser_obj(parser);
	else if (array_parser->model == PARSER_MODEL_NT_ARRAY)
		obj = args->sarray + (parser->size * args->index);

	if ((rc = parse(obj, NO_VAL, parser, src, args->args, ppath))) {
		log_flag(DATA, "%s object at 0x%"PRIxPTR" freed due to parser error: %s",
			 parser->obj_type_string, (uintptr_t) obj,
			 slurm_strerror(rc));
		if (array_parser->model == PARSER_MODEL_NT_PTR_ARRAY)
			free_parser_obj(parser, obj);
		FREE_NULL_DATA(ppath);
		return DATA_FOR_EACH_FAIL;
	}

	if (array_parser->model == PARSER_MODEL_NT_PTR_ARRAY) {
		xassert(!args->array[args->index]);
		args->array[args->index] = obj;
	}

	args->index++;

	FREE_NULL_DATA(ppath);
	return DATA_FOR_EACH_CONT;
}

static int _parse_nt_array(const parser_t *const parser, void *dst, data_t *src,
			   args_t *args, data_t *parent_path)
{
	int rc = SLURM_SUCCESS;
	foreach_nt_array_t fargs = {
		.magic = MAGIC_FOREACH_NT_ARRAY,
		.array_parser = parser,
		.parser = find_parser_by_type(parser->array_type),
		.args = args,
		.parent_path = parent_path,
		.index = -1,
	};
	char *path = NULL;

	xassert(args->magic == MAGIC_ARGS);

	if ((data_get_type(src) != DATA_TYPE_LIST) &&
	    (data_convert_type(src, DATA_TYPE_STRING) != DATA_TYPE_STRING)) {
		rc = on_error(PARSING, parser->type, args,
			      ESLURM_DATA_EXPECTED_LIST,
			      set_source_path(&path, args, parent_path),
			      __func__, "Expected List but found a %s",
			      data_get_type_string(src));
		goto cleanup;
	}

	/* assume list can parse all entries */
	if (parser->model == PARSER_MODEL_NT_PTR_ARRAY)
		fargs.array = xcalloc(data_get_list_length(src) + 1,
				      sizeof(*fargs.array));
	else if (parser->model == PARSER_MODEL_NT_ARRAY)
		fargs.sarray = xcalloc(data_get_list_length(src) + 1,
				       fargs.parser->size);

	/* verify new array actually allocated */;
	xassert((fargs.array && (xsize(fargs.array) > 0)) ^
		(fargs.sarray && (xsize(fargs.sarray) > 0)));

	if (data_get_type(src) == DATA_TYPE_LIST) {
		if (data_list_for_each(src, _foreach_array_entry, &fargs) < 0)
			goto cleanup;
	} else if (data_get_type(src) == DATA_TYPE_STRING) {
		/* Assume List is just a single entry */
		if (_foreach_array_entry(src, &fargs) != DATA_FOR_EACH_CONT)
			rc = ESLURM_REST_FAIL_PARSING;
	}

	if (parser->model == PARSER_MODEL_NT_PTR_ARRAY) {
		void ***array_ptr = dst;
		xassert(!*array_ptr);
		SWAP(*array_ptr, fargs.array);
	} else if (parser->model == PARSER_MODEL_NT_ARRAY) {
		void **array_ptr = dst;
		xassert(!*array_ptr);
		SWAP(*array_ptr, fargs.sarray);
	}

cleanup:
	xfree(path);

	if (fargs.array) {
		/* must have failed - cleanup the memory */
		for (int i = 0; fargs.array[i]; i++)
			free_parser_obj(parser, &fargs.array[i]);
		xfree(fargs.array);
	} else if (fargs.sarray) {
		xfree(fargs.sarray);
	}

	return rc;
}

static void _parser_linked_flag(args_t *args, const parser_t *const array,
				const parser_t *const parser, data_t *src,
				void *dst, data_t *parent_path,
				const flag_bit_t *bit, uint64_t *set)
{
	char *path = NULL;
	data_t *ppath = NULL;
	bool matched;

	src = data_resolve_dict_path(src, bit->name);

	if (!is_fast_mode(args)) {
		ppath = data_copy(NULL, parent_path);
		openapi_append_rel_path(ppath, bit->name);
		set_source_path(&path, args, ppath);
	}

	if (!src) {
		matched = false;
	} else if (data_convert_type(src, DATA_TYPE_BOOL) != DATA_TYPE_BOOL) {
		matched = false;

		on_warn(PARSING, parser->type, args, path, __func__,
			"Unable to convert to boolean from %s. Flag %s is being treated as false.",
			data_get_type_string(src), bit->name);

	} else {
		matched = data_get_bool(src);
	}

	if (bit->type == FLAG_BIT_TYPE_BIT)
		_set_flag_bit(parser, dst, bit, matched, path, src);
	else if (bit->type == FLAG_BIT_TYPE_EQUAL) {
		if (matched || ((~(*set) & bit->mask) == bit->mask))
			_set_flag_bit_equal(parser, dst, bit, matched, path,
					    src);
		*set |= bit->mask;
	} else if (bit->type == FLAG_BIT_TYPE_REMOVED) {
		if (matched && !is_fast_mode(args))
			on_warn(PARSING, parser->type, args, path, __func__,
				"Ignoring deprecated flag: %s", bit->name);
	} else {
		fatal_abort("%s: invalid bit_flag_t", __func__);
	}

	log_flag(DATA, "%s: parsed flag %s{%s(0x%" PRIxPTR ")} to %s(0x%" PRIxPTR "+%zd)->%s & 0x%"PRIx64" & %s=0x%"PRIx64" via array parser %s(0x%" PRIxPTR ")=%s(0x%" PRIxPTR ")",
		 __func__, path, data_get_type_string(src),
		 (uintptr_t) src, array->obj_type_string, (uintptr_t) dst,
		 parser->ptr_offset, parser->field_name, bit->mask,
		 bit->flag_name, bit->value, parser->obj_type_string,
		 (uintptr_t) parser, array->type_string, (uintptr_t) array);

	xfree(path);
	FREE_NULL_DATA(ppath);
}

static data_for_each_cmd_t _foreach_parse_marray(const char *key, data_t *data,
						 void *arg)
{
	parse_marray_args_t *aargs = arg;
	parse_marray_args_t cargs = *aargs;
	args_t *args = aargs->args;
	const parser_t *const array = aargs->array;
	char *path = NULL;

	xassert(aargs->magic == MAGIC_FOREACH_PARSE_MARRAY);
	xassert(cargs.magic == MAGIC_FOREACH_PARSE_MARRAY);
	xassert(array->model == PARSER_MODEL_ARRAY);
	xassert(!is_fast_mode(args));

	cargs.parent_path = data_copy(NULL, aargs->parent_path);
	openapi_append_rel_path(cargs.parent_path, key);

	cargs.path = data_copy(NULL, aargs->path);
	data_set_string(data_list_append(cargs.path), key);

	for (int i = 0; i < array->field_count; i++) {
		bool match;
		const parser_t *const parser = &array->fields[i];
		data_t *fpath;

		if (parser->model == PARSER_MODEL_ARRAY_SKIP_FIELD)
			continue;

		if (parser->model ==
		    PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD) {
			const parser_t *const fp =
				find_parser_by_type(parser->type);

			for (int i = 0; i < fp->flag_bit_array_count; i++) {
				const flag_bit_t *bit = &fp->flag_bit_array[i];

				if (!xstrcasecmp(key, bit->name)) {
					if (slurm_conf.debug_flags &
					    DEBUG_FLAG_DATA) {
						char *p = NULL;
						data_list_join_str(&p,
								   cargs.path,
								   "/");

						log_flag(DATA, "%s: matched %s as bitflag %s",
						      __func__, p, bit->name);

						xfree(p);
					}
					goto cleanup;
				}
			}
		}

		fpath = data_new();
		(void) data_list_split_str(fpath, parser->key, "/");
		match = data_check_match(fpath, cargs.path, false);
		FREE_NULL_DATA(fpath);

		if (match) {
			if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
				char *p = NULL;
				data_list_join_str(&p, cargs.path, "/");
				log_flag(DATA, "%s: matched %s to %s",
				      __func__, p, parser->key);
				xfree(p);
			}
			goto cleanup;
		}
	}

	if (data_get_type(data) == DATA_TYPE_DICT) {
		/* still unknown, so try next level of tree */
		(void) data_dict_for_each(data, _foreach_parse_marray, &cargs);
		goto cleanup;
	}

	on_warn(PARSING, array->type, args,
		set_source_path(&path, args, cargs.parent_path),
		__func__, "Ignoring unknown field \"%s\" of type %s in %s", key,
		data_get_type_string(data), array->type_string);

cleanup:
	FREE_NULL_DATA(cargs.path);
	FREE_NULL_DATA(cargs.parent_path);
	xfree(path);
	return DATA_FOR_EACH_CONT;
}

/*
 * Try to guess if the user actually set the value or if the value was dumped
 * with the other oversubsribed values which means it doesn't need to be logged
 */
static int _is_duplicate_linked_parser_value(args_t *args,
					     const parser_t *const array,
					     const parser_t *const parser,
					     data_t *src_obj, data_t *src,
					     data_t *parent_path)
{
	if (parser->field_name_overloads == 1)
		return false;

	for (int i = 0; i < array->field_count; i++) {
		if ((array->fields[i].field_name_overloads != 1) &&
		    !xstrcmp(array->fields[i].field_name, parser->field_name) &&
		    !data_check_match(src,
				      data_key_get(src_obj,
						   array->fields[i].key),
				      false)) {
			return false;
		}
	}

	return true;
}

/* parser linked parser inside of parser array */
static int _parser_linked(args_t *args, const parser_t *const array,
			  const parser_t *const parser, data_t *src, void *dst,
			  data_t *parent_path)
{
	int rc = SLURM_ERROR;
	data_t *ppath = NULL, *src_obj = src;
	char *path = NULL;

	check_parser(parser);
	verify_parser_sliced(parser);

	if (parser->model ==
	    PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD) {
		const parser_t *const fp = find_parser_by_type(parser->type);
		uint64_t set = 0;

		rc = SLURM_SUCCESS;

		if (parser->ptr_offset != NO_VAL)
			dst += parser->ptr_offset;

		for (int i = 0; i < fp->flag_bit_array_count; i++) {
			const flag_bit_t *bit = &fp->flag_bit_array[i];

			_parser_linked_flag(args, array, fp, src, dst,
					    parent_path, bit, &set);
		}

		goto cleanup;
	}

	if (!is_fast_mode(args))
		ppath = data_copy(NULL, parent_path);

	/* only look for child via key if there was one defined */
	if (parser->key) {
		src = data_resolve_dict_path(src, parser->key);

		if (!is_fast_mode(args))
			openapi_append_rel_path(ppath, parser->key);
	}

	if (parser->model == PARSER_MODEL_ARRAY_REMOVED_FIELD) {
		log_flag(DATA, "%s: skip parsing removed %s object %s(0x%" PRIxPTR ") via parser %s(0x%" PRIxPTR ")",
			__func__, set_source_path(&path, args, ppath),
			parser->obj_type_string, (uintptr_t) dst,
			parser->type_string, (uintptr_t) src);
		rc = SLURM_SUCCESS;
		goto cleanup;
	}

	if (!src) {
		if (parser->required) {
			if ((rc = on_error(PARSING, parser->type, args,
					   ESLURM_DATA_PATH_NOT_FOUND,
					   set_source_path(&path, args, ppath),
					   __func__,
					   "Missing required field '%s' in dictionary",
					   parser->key)))
				goto cleanup;
		} else {
			/* field is missing but not required */
			log_flag(DATA, "%s: skip parsing missing %s to object %s(0x%" PRIxPTR "+%zd)%s%s via parser %s(0x%" PRIxPTR ")",
				__func__, path, parser->obj_type_string,
				(uintptr_t) dst,
				(parser->ptr_offset == NO_VAL ?
					 0 :
					 parser->ptr_offset),
				(parser->field_name ? "->" : ""),
				(parser->field_name ? parser->field_name : ""),
				parser->type_string, (uintptr_t) src);

			rc = SLURM_SUCCESS;
			goto cleanup;
		}
	}

	if (parser->ptr_offset != NO_VAL)
		dst += parser->ptr_offset;

	if (parser->model == PARSER_MODEL_ARRAY_SKIP_FIELD) {
		log_flag(DATA, "%s: SKIP: parsing %s{%s(0x%" PRIxPTR ")} to %s(0x%" PRIxPTR "+%zd)%s%s=%s(0x%" PRIxPTR ") via array parser %s(0x%" PRIxPTR ")=%s(0x%" PRIxPTR ")",
			 __func__, parser->field_name,
			 data_get_type_string(src),
			 (uintptr_t) src, parser->obj_type_string,
			 (uintptr_t) dst, parser->ptr_offset,
			 (parser->field_name ? "->" : ""),
			 (parser->field_name ? parser->field_name : ""),
			 parser->obj_type_string, (uintptr_t) src,
			 parser->type_string, (uintptr_t) array,
			 parser->type_string, (uintptr_t) parser);
		rc = SLURM_SUCCESS;
		goto cleanup;
	}

	xassert(parser->model == PARSER_MODEL_ARRAY_LINKED_FIELD);

	if (!is_fast_mode(args) && parser->deprecated &&
	    (parser->deprecated <= SLURM_MIN_PROTOCOL_VERSION) &&
	    !_is_duplicate_linked_parser_value(args, array, parser, src_obj,
					       src, parent_path)) {
		on_warn(PARSING, parser->type, args,
			set_source_path(&path, args, ppath), __func__,
			"Field \"%s\" is deprecated", parser->key);
	}

	log_flag(DATA, "%s: BEGIN: parsing %s{%s(0x%" PRIxPTR ")} to %s(0x%" PRIxPTR "+%zd)%s%s=%s(0x%" PRIxPTR ") via array parser %s(0x%" PRIxPTR ")=%s(0x%" PRIxPTR ")",
		 __func__, path, data_get_type_string(src),
		 (uintptr_t) src, array->obj_type_string, (uintptr_t) dst,
		 array->ptr_offset, (array->field_name ? "->" : ""),
		 (array->field_name ? array->field_name : ""),
		 parser->obj_type_string, (uintptr_t) src, array->type_string,
		 (uintptr_t) array, parser->type_string, (uintptr_t) parser);

	rc = parse(dst, NO_VAL, find_parser_by_type(parser->type), src, args,
		   ppath);

	log_flag(DATA, "%s: END: parsing %s{%s(0x%" PRIxPTR ")} to %s(0x%" PRIxPTR "+%zd)%s%s=%s(0x%" PRIxPTR ") via array parser %s(0x%" PRIxPTR ")=%s(0x%" PRIxPTR ") rc[%d]:%s",
		 __func__, path, data_get_type_string(src),
		 (uintptr_t) src, array->obj_type_string, (uintptr_t) dst,
		 array->ptr_offset, (array->field_name ? "->" : ""),
		 (array->field_name ? array->field_name : ""),
		 parser->obj_type_string, (uintptr_t) parser,
		 array->type_string, (uintptr_t) array, parser->type_string,
		 (uintptr_t) parser, rc, slurm_strerror(rc));

cleanup:
	FREE_NULL_DATA(ppath);
	xfree(path);
	return rc;
}

static void _parse_check_openapi(const parser_t *const parser, data_t *src,
				 args_t *args, data_t *parent_path)
{
	char *path = NULL;
	const char *oas_type, *oas_format, *found_type, *found_format;
	data_type_t oas_data_type;
	openapi_type_format_t found;

	if (data_get_type(src) == DATA_TYPE_NULL)
		return;

	if (parser->obj_openapi == OPENAPI_FORMAT_INVALID)
		return;

	if (data_get_type(src) ==
	    openapi_type_format_to_data_type(parser->obj_openapi))
		return;

	oas_type = openapi_type_format_to_type_string(parser->obj_openapi);
	oas_format =
		openapi_type_format_to_format_string(parser->obj_openapi);
	found = openapi_data_type_to_type_format(data_get_type(src));
	found_type = openapi_type_format_to_type_string(found);
	found_format = openapi_type_format_to_format_string(found);
	oas_data_type = openapi_type_format_to_data_type(parser->obj_openapi);

	xassert(!is_complex_mode(args));

	/*
	 * Warn as this is user provided data and the parser may accept
	 * the format anyway. Steer the user towards the formats given
	 * in the OpenAPI specification as set in the parser.
	 */
	on_warn(PARSING, parser->type, args,
		set_source_path(&path, args, parent_path), __func__,
		"Expected OpenAPI type=%s%s%s (Slurm type=%s) but got OpenAPI type=%s%s%s (Slurm type=%s): %pd",
		oas_type, (oas_format ? " format=" : ""),
		(oas_format ? oas_format : ""),
		data_type_to_string(oas_data_type), found_type,
		(found_format ? " format=" : ""),
		(found_format ? found_format : ""), data_get_type_string(src),
		src);

	xfree(path);
}

extern int parse(void *dst, ssize_t dst_bytes, const parser_t *const parser,
		 data_t *src, args_t *args, data_t *parent_path)
{
	int rc = SLURM_SUCCESS;
	char *path = NULL;

	check_parser(parser);
	xassert(parser->model != PARSER_MODEL_ARRAY_SKIP_FIELD);
	xassert(args->magic == MAGIC_ARGS);
	xassert(data_get_type(src) != DATA_TYPE_NONE);
	xassert(dst);
	/*
	 * Make sure the target object is the same size since there is no
	 * way to dump value of __typeof__ as a value in C99.
	 */
	xassert((dst_bytes == NO_VAL) || (dst_bytes == parser->size) ||
		(parser->model == PARSER_MODEL_ALIAS));

	if ((rc = load_prereqs(PARSING, parser, args)))
		goto cleanup;

	if (!src) {
		if (parser->required) {
			if ((rc = on_error(PARSING, parser->type, args,
					   ESLURM_DATA_PATH_NOT_FOUND,
					   set_source_path(&path, args,
							   parent_path),
					   __func__,
					   "Missing required field '%s' in dictionary",
					   parser->key)))
				goto cleanup;
		} else {
			/* field is missing but not required */
			log_flag(DATA, "%s: skip parsing missing %s to %zd byte object %s(0x%" PRIxPTR "+%zd)%s%s via parser %s(0x%" PRIxPTR ")",
				__func__, set_source_path(&path, args,
							  parent_path),
				(dst_bytes == NO_VAL ? -1 : dst_bytes),
				parser->obj_type_string, (uintptr_t) dst,
				(parser->ptr_offset == NO_VAL ?
					 0 :
					 parser->ptr_offset),
				(parser->field_name ? "->" : ""),
				(parser->field_name ? parser->field_name : ""),
				parser->type_string, (uintptr_t) parser);

			rc = SLURM_SUCCESS;
			goto cleanup;
		}
	}

	log_flag(DATA, "%s: BEGIN: parsing %s{%s(0x%" PRIxPTR ")} to %zd byte object %s(0x%" PRIxPTR "+%zd)%s%s via parser %s(0x%" PRIxPTR ")",
		 __func__, set_source_path(&path, args, parent_path),
		 data_get_type_string(src),
		 (uintptr_t) src, (dst_bytes == NO_VAL ? -1 : dst_bytes),
		 parser->obj_type_string, (uintptr_t) dst,
		 (parser->ptr_offset == NO_VAL ? 0 : parser->ptr_offset),
		 (parser->field_name ? "->" : ""),
		 (parser->field_name ? parser->field_name : ""),
		 parser->type_string, (uintptr_t) parser);

	switch (parser->model) {
	case PARSER_MODEL_REMOVED:
		if (data_get_type(src) != DATA_TYPE_NULL)
			on_warn(PARSING, parser->type, args, path, __func__,
				"Ignoring value for removed parser");
		rc = SLURM_SUCCESS;
		break;
	case PARSER_MODEL_FLAG_ARRAY:
		verify_parser_not_sliced(parser);
		rc = _parse_flag(dst, parser, src, args, parent_path);
		break;
	case PARSER_MODEL_LIST:
		xassert(parser->list_type > DATA_PARSER_TYPE_INVALID);
		xassert(parser->list_type < DATA_PARSER_TYPE_MAX);
		verify_parser_not_sliced(parser);
		xassert((dst_bytes == NO_VAL) || (dst_bytes == sizeof(list_t *)));
		xassert(!parser->parse);
		rc = _parse_list(parser, dst, src, args, parent_path);
		break;
	case PARSER_MODEL_ARRAY:
	{
		xassert(parser->fields);
		verify_parser_not_sliced(parser);

		if (data_get_type(src) != DATA_TYPE_DICT) {
			rc = on_error(PARSING, parser->type, args,
				      ESLURM_DATA_EXPECTED_DICT,
				      set_source_path(&path, args, parent_path),
				      __func__,
				      "Rejecting %s when dictionary expected",
				      data_get_type_string(src));
		} else {
			/* recursively run the child parsers */
			for (int i = 0; !rc && (i < parser->field_count); i++)
				rc = _parser_linked(args, parser,
						    &parser->fields[i], src,
						    dst, parent_path);

			if (!is_fast_mode(args)) {
				parse_marray_args_t aargs = {
					.magic = MAGIC_FOREACH_PARSE_MARRAY,
					.args = args,
					.array = parser,
					.parent_path = parent_path,
				};

				aargs.path = data_set_list(data_new());
				(void) data_dict_for_each(src,
							  _foreach_parse_marray,
							  &aargs);
				FREE_NULL_DATA(aargs.path);
			}
		}
		break;
	}
	case PARSER_MODEL_PTR:
		verify_parser_not_sliced(parser);
		rc = _parse_pointer(parser, dst, src, args, parent_path);
		break;
	case PARSER_MODEL_NT_PTR_ARRAY:
	case PARSER_MODEL_NT_ARRAY:
		verify_parser_not_sliced(parser);
		rc = _parse_nt_array(parser, dst, src, args, parent_path);
		break;
	case PARSER_MODEL_SIMPLE:
	case PARSER_MODEL_COMPLEX:
		xassert(parser->parse != _parse_list);
		verify_parser_not_sliced(parser);

		if (!is_fast_mode(args) && !is_complex_mode(args))
			_parse_check_openapi(parser, src, args, parent_path);

		rc = parser->parse(parser, dst, src, args, parent_path);
		break;
	case PARSER_MODEL_ALIAS:
		rc = parse(dst, dst_bytes,
			   find_parser_by_type(parser->alias_type), src, args,
			   parent_path);
		break;
	case PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD:
	case PARSER_MODEL_ARRAY_LINKED_FIELD:
		fatal_abort("%s: link model not allowed %u",
			    __func__, parser->model);
	case PARSER_MODEL_ARRAY_SKIP_FIELD:
		fatal_abort("%s: skip model not allowed %u",
			    __func__, parser->model);
	case PARSER_MODEL_ARRAY_REMOVED_FIELD:
		fatal_abort("%s: removed model not allowed %u",
			    __func__, parser->model);
	case PARSER_MODEL_INVALID:
	case PARSER_MODEL_MAX:
		fatal_abort("%s: invalid model %u", __func__, parser->model);
	}

cleanup:
	log_flag(DATA, "%s: END: parsing %s{%s(0x%" PRIxPTR ")} to %zd byte object %s(0x%" PRIxPTR "+%zd)%s%s via parser %s(0x%" PRIxPTR ") rc[%d]:%s",
		 __func__, set_source_path(&path, args, parent_path),
		 data_get_type_string(src), (uintptr_t) src,
		 (dst_bytes == NO_VAL ? -1 : dst_bytes),
		 parser->obj_type_string, (uintptr_t) dst, (parser->ptr_offset
							    == NO_VAL ? 0 :
							    parser->ptr_offset),
		 (parser->field_name ? "->" : ""), (parser->field_name ?
						    parser->field_name : ""),
		 parser->type_string, (uintptr_t) parser, rc,
		 slurm_strerror(rc));

	xfree(path);

	return rc;
}

static bool _match_flag_bit(const parser_t *const parser, void *src,
			    const flag_bit_t *bit, uint64_t used_equal_bits)
{
	const uint64_t v = bit->mask & bit->value;

	if (used_equal_bits & bit->mask)
		return false;

	/* C allows compiler to choose a size for the enum */
	if (parser->size == sizeof(uint64_t)) {
		uint64_t *flags = src;
		return ((*flags & v) == v);
	} else if (parser->size == sizeof(uint32_t)) {
		uint32_t *flags = src;
		return ((*flags & v) == v);
	} else if (parser->size == sizeof(uint16_t)) {
		uint16_t *flags = src;
		return ((*flags & v) == v);
	} else if (parser->size == sizeof(uint8_t)) {
		uint8_t *flags = src;
		return ((*flags & v) == v);
	}

	fatal("%s: unexpected enum size: %zu", __func__, parser->size);
}

static bool _match_flag_equal(const parser_t *const parser, void *src,
			      const flag_bit_t *bit,
			      uint64_t *used_equal_bits_ptr)
{
	bool found;
	const uint64_t v = bit->mask & bit->value;

	/* C allows compiler to choose a size for the enum */
	if (parser->size == sizeof(uint64_t)) {
		uint64_t *flags = src;
		found = ((*flags & bit->mask) == v);
	} else if (parser->size == sizeof(uint32_t)) {
		uint32_t *flags = src;
		found = ((*flags & bit->mask) == v);
	} else if (parser->size == sizeof(uint16_t)) {
		uint16_t *flags = src;
		found = ((*flags & bit->mask) == v);
	} else if (parser->size == sizeof(uint8_t)) {
		uint8_t *flags = src;
		found = ((*flags & bit->mask) == v);
	} else {
		fatal("%s: unexpected enum size: %zu", __func__, parser->size);
	}

	if (found)
		*used_equal_bits_ptr |= bit->mask;

	return found;
}

static void _dump_flag_bit_array_flag(args_t *args, void *src, data_t *dst,
				      const parser_t *const parser,
				      const flag_bit_t *bit, bool set_bool,
				      uint64_t *used_equal_bits)
{
	bool found;

	if (bit->hidden)
		return;

	if (bit->type == FLAG_BIT_TYPE_BIT)
		found = _match_flag_bit(parser, src, bit, *used_equal_bits);
	else if (bit->type == FLAG_BIT_TYPE_EQUAL)
		found = _match_flag_equal(parser, src, bit, used_equal_bits);
	else if (bit->type == FLAG_BIT_TYPE_REMOVED)
		found = false;
	else
		fatal_abort("%s: invalid bit_flag_t", __func__);

	if (set_bool)
		data_set_bool(dst, found);
	else if (found) {
		data_t *dst_flag;

		if (parser->single_flag)
			dst_flag = dst;
		else
			dst_flag = data_list_append(dst);

		data_set_string(dst_flag, bit->name);
	}

	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		const char *type;
		uint64_t value;

		if (parser->size == sizeof(uint64_t)) {
			uint64_t *flags = src;
			value = *flags;
		} else if (parser->size == sizeof(uint32_t)) {
			uint32_t *flags = src;
			value = *flags;
		} else if (parser->size == sizeof(uint16_t)) {
			uint16_t *flags = src;
			value = *flags;
		} else if (parser->size == sizeof(uint8_t)) {
			uint8_t *flags = src;
			value = *flags;
		} else {
			fatal_abort("invalid parser flag size: %zu",
				    parser->size);
		}

		if (bit->type == FLAG_BIT_TYPE_BIT)
			type = "bit";
		else if (bit->type == FLAG_BIT_TYPE_EQUAL)
			type = "bit-equals";
		else if (bit->type == FLAG_BIT_TYPE_REMOVED)
			type = "removed";
		else
			type = "INVALID";

		log_flag(DATA, "%s: %s \"%s\" flag %s %s(%s[0x%"PRIx64"] & %s[0x%"PRIx64"]) & 0x%"PRIx64" = 0x%"PRIx64" for %zd byte %s(0x%" PRIxPTR "+%zd)->%s with parser %s(0x%" PRIxPTR ") to data %s[0x%" PRIxPTR "]",
			 __func__, (found ? "appending matched" : "skipping"),
			 bit->name, type, bit->name, bit->mask_name, bit->mask,
			 bit->flag_name, bit->value, value,
			 (bit->mask & value & bit->value), parser->size,
			 parser->obj_type_string, (uintptr_t) src,
			 parser->ptr_offset, parser->field_name,
			 parser->type_string, (uintptr_t) parser,
			 data_get_type_string(dst),
			 (uintptr_t) dst);
	}
}

static int _dump_flag_bit_array(args_t *args, void *src, data_t *dst,
				const parser_t *const parser)
{
	int rc = SLURM_SUCCESS;
	uint64_t used_equal_bits = 0;

	xassert(args->magic == MAGIC_ARGS);
	check_parser(parser);

	if (!parser->single_flag) {
		if (data_get_type(dst) == DATA_TYPE_NULL)
			data_set_list(dst);
		if (data_get_type(dst) != DATA_TYPE_LIST)
			return ESLURM_DATA_CONV_FAILED;
	}

	for (int8_t i = 0; !rc && (i < parser->flag_bit_array_count); i++)
		_dump_flag_bit_array_flag(args, src, dst, parser,
					  &parser->flag_bit_array[i], false,
					  &used_equal_bits);

	return SLURM_SUCCESS;
}

static int _foreach_dump_list(void *obj, void *arg)
{
	foreach_list_t *args = arg;
	data_t *item = data_list_append(args->dlist);

	xassert(args->magic == MAGIC_FOREACH_LIST);
	xassert(args->args->magic == MAGIC_ARGS);
	check_parser(args->parser);
	xassert(args->parser->ptr_offset == NO_VAL);

	/* we don't know the size of the items in the list */
	if (dump(&obj, NO_VAL, NULL,
		 find_parser_by_type(args->parser->list_type), item,
		 args->args))
		return -1;

	return 0;
}

static int _dump_list(const parser_t *const parser, void *src, data_t *dst,
		      args_t *args)
{
	list_t **list_ptr = src;
	foreach_list_t fargs = {
		.magic = MAGIC_FOREACH_LIST,
		.args = args,
		.parser = parser,
		.list = (list_ptr ? *list_ptr : NULL),
		.dlist = dst,
	};

	xassert(args->magic == MAGIC_ARGS);
	check_parser(parser);
	xassert(!list_ptr || !*list_ptr || (list_count(*list_ptr) >= 0));
	xassert((data_get_type(dst) == DATA_TYPE_NULL) ||
		(data_get_type(dst) == DATA_TYPE_LIST));

	if (data_get_type(dst) != DATA_TYPE_LIST)
		data_set_list(dst);

	if (!fargs.list || list_is_empty(fargs.list)) {
		/* list is empty */
		return SLURM_SUCCESS;
	}

	if (list_for_each(fargs.list, _foreach_dump_list, &fargs) < 0) {
		return on_error(DUMPING, parser->type, args, SLURM_ERROR,
				"_foreach_dump_list", __func__,
				"dumping list failed");
	}

	return SLURM_SUCCESS;
}

static int _dump_pointer(const parser_t *const field_parser,
			 const parser_t *const parser, void *src, data_t *dst,
			 args_t *args)
{
	const parser_t *pt = find_parser_by_type(parser->pointer_type);
	void **ptr = src;

	if (!*ptr) {
		if (is_complex_mode(args)) {
			xassert(data_get_type(dst) == DATA_TYPE_NULL);
			return SLURM_SUCCESS;
		}

		/* Fully resolve pointer on NULL to use correct model */
		pt = unalias_parser(pt);

		if (parser->allow_null_pointer ||
		    (field_parser && !field_parser->required)) {
			xassert(data_get_type(dst) == DATA_TYPE_NULL);
		} else if ((pt->model == PARSER_MODEL_ARRAY) ||
		    (pt->obj_openapi == OPENAPI_FORMAT_OBJECT)) {
			/*
			 * OpenAPI clients can't handle a null instead of an
			 * object. Work around by placing an empty dictionary
			 * instead of null.
			 */
			data_set_dict(dst);
		} else if ((pt->model == PARSER_MODEL_LIST) ||
			   (pt->model == PARSER_MODEL_NT_ARRAY) ||
			   (pt->model == PARSER_MODEL_NT_PTR_ARRAY) ||
			   (pt->obj_openapi == OPENAPI_FORMAT_ARRAY)) {
			/*
			 * OpenAPI clients can't handle a null instead of an
			 * array. Work around by placing an empty list instead
			 * of null.
			 */
			data_set_list(dst);
		}

		return SLURM_SUCCESS;
	}

	return dump(*ptr, NO_VAL, NULL, pt, dst, args);
}

static int _dump_nt_array(const parser_t *const parser, void *src, data_t *dst,
			  args_t *args)
{
	int rc = SLURM_SUCCESS;

	data_set_list(dst);

	if (parser->model == PARSER_MODEL_NT_PTR_ARRAY) {
		void ***array_ptr = src;
		void **array;

		if (!(array = *array_ptr))
			return SLURM_SUCCESS;

		for (int i = 0; !rc && array[i]; i++) {
			rc = dump(array[i], NO_VAL,
				  NULL, find_parser_by_type(parser->array_type),
				  data_list_append(dst), args);
		}
	} else if (parser->model == PARSER_MODEL_NT_ARRAY) {
		const parser_t *const ap =
			find_parser_by_type(parser->array_type);
		void **array = src;

		if (!*array)
			return SLURM_SUCCESS;

		for (int i = 0; !rc; i++) {
			bool done = true;
			void *ptr = *array + (ap->size * i);

			/* check every byte of object is zero */
			for (int j = 0; j < ap->size; j++)
				if (((char *) ptr)[j])
					done = false;

			if (done)
				break;

			rc = dump(ptr, NO_VAL, NULL,
				  find_parser_by_type(parser->array_type),
				  data_list_append(dst), args);
		}
	} else {
		fatal_abort("invalid model");
	}

	return rc;
}

static void _dump_removed(const parser_t *parser, data_t *dst, args_t *args)
{
	if (is_complex_mode(args)) {
		data_set_null(dst);
		return;
	}

	while ((parser->model == PARSER_MODEL_ARRAY_REMOVED_FIELD) ||
	       parser->pointer_type) {
		parser = unalias_parser(parser);

		while (parser->model == PARSER_MODEL_ARRAY_REMOVED_FIELD)
			parser = find_parser_by_type(parser->type);
	}

	xassert(parser->model != PARSER_MODEL_ARRAY_REMOVED_FIELD);
	xassert(parser->model !=
		PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD);
	xassert(parser->model > PARSER_MODEL_INVALID);
	xassert(parser->model < PARSER_MODEL_MAX);

	switch (parser->obj_openapi) {
	case OPENAPI_FORMAT_INT:
	case OPENAPI_FORMAT_INT32:
	case OPENAPI_FORMAT_INT64:
		data_set_int(dst, 0);
		break;
	case OPENAPI_FORMAT_NUMBER:
	case OPENAPI_FORMAT_FLOAT:
	case OPENAPI_FORMAT_DOUBLE:
		data_set_float(dst, 0);
		break;
	case OPENAPI_FORMAT_STRING:
	case OPENAPI_FORMAT_PASSWORD:
		data_set_string(dst, "");
		break;
	case OPENAPI_FORMAT_BOOL:
		data_set_bool(dst, false);
	case OPENAPI_FORMAT_OBJECT:
		data_set_dict(dst);
		break;
	case OPENAPI_FORMAT_ARRAY:
		data_set_list(dst);
		break;
	case OPENAPI_FORMAT_MAX:
	case OPENAPI_FORMAT_INVALID:
		/* Should never happen but avoid crashing clients */
		xassert(false);
		data_set_null(dst);
	};
}

static int _dump_linked(args_t *args, const parser_t *const array,
			const parser_t *const parser, void *src, data_t *dst)
{
	int rc = SLURM_SUCCESS;

	check_parser(parser);
	verify_parser_sliced(parser);

	if ((parser->ptr_offset != NO_VAL) && src)
		src += parser->ptr_offset;

	/*
	 * Only look for child via key if there was one defined
	 */
	if (parser->key) {
		/*
		 * Detect duplicate keys
		 */
		xassert(!data_resolve_dict_path(dst, parser->key));
		dst = data_define_dict_path(dst, parser->key);
	}

	xassert(dst && (data_get_type(dst) != DATA_TYPE_NONE));

	if (parser->model == PARSER_MODEL_ARRAY_SKIP_FIELD) {
		log_flag(DATA, "SKIP: %s parser %s->%s(0x%" PRIxPTR ") for %s(0x%" PRIxPTR ")->%s(+%zd) for data(0x%" PRIxPTR ")/%s(0x%" PRIxPTR ")",
			 parser->obj_type_string,
			 array->type_string,
			 parser->type_string, (uintptr_t)
			 parser, array->obj_type_string,
			 (uintptr_t) src, array->field_name,
			 array->ptr_offset, (uintptr_t) dst,
			 array->key, (uintptr_t) dst);
		return SLURM_SUCCESS;
	}

	if (parser->model == PARSER_MODEL_ARRAY_REMOVED_FIELD) {
		const parser_t *const rparser =
			find_parser_by_type(parser->type);

		log_flag(DATA, "removed: %s parser %s->%s(0x%" PRIxPTR ") for %s(0x%" PRIxPTR ") for data(0x%" PRIxPTR ")/%s(0x%" PRIxPTR ")",
			 parser->obj_type_string,
			 array->type_string,
			 parser->type_string, (uintptr_t)
			 parser, array->obj_type_string,
			 (uintptr_t) src, (uintptr_t) dst,
			 array->key, (uintptr_t) dst);

		_dump_removed(rparser, dst, args);

		return SLURM_SUCCESS;
	}

	if (parser->model ==
	    PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD) {
		uint64_t used_equal_bits = 0;

		if (data_get_type(dst) == DATA_TYPE_NULL)
			data_set_dict(dst);

		for (int i = 0; i < parser->flag_bit_array_count; i++) {
			const flag_bit_t *bit = &parser->flag_bit_array[i];

			if (bit->hidden)
				continue;

			data_t *bit_dst = data_define_dict_path(dst, bit->name);

			xassert(src);
			_dump_flag_bit_array_flag(args, src, bit_dst, parser,
						  bit, true, &used_equal_bits);
		}

		return SLURM_SUCCESS;
	}

	xassert(parser->model == PARSER_MODEL_ARRAY_LINKED_FIELD);

	log_flag(DATA, "BEGIN: dumping %s parser %s->%s(0x%" PRIxPTR ") for %s(0x%" PRIxPTR ")->%s(+%zd) for data(0x%" PRIxPTR ")/%s(0x%" PRIxPTR ")",
		 parser->obj_type_string, array->type_string,
		 parser->type_string, (uintptr_t) parser,
		 parser->obj_type_string, (uintptr_t) src, array->field_name,
		 array->ptr_offset, (uintptr_t) dst, array->key,
		 (uintptr_t) dst);

	rc = dump(src, NO_VAL, parser, find_parser_by_type(parser->type), dst,
		  args);

	log_flag(DATA, "END: dumping %s parser %s->%s(0x%" PRIxPTR ") for %s(0x%" PRIxPTR ")->%s(+%zd) for data(0x%" PRIxPTR ")/%s(0x%" PRIxPTR ")",
		 parser->obj_type_string, array->type_string,
		 parser->type_string, (uintptr_t) parser,
		 array->obj_type_string, (uintptr_t) src, array->field_name,
		 array->ptr_offset, (uintptr_t) dst, array->key,
		 (uintptr_t) dst);

	return rc;
}

static void _check_dump(const parser_t *const parser, data_t *dst, args_t *args)
{
	/*
	 * Resultant dump must be the proscribed OpenAPI compatible data_t type.
	 * Anything else will break most generated OpenAPI clients.
	 */
	if (parser->obj_openapi == OPENAPI_FORMAT_INVALID)
		return;

	if (!is_complex_mode(args)) {
		xassert(data_get_type(dst) ==
			openapi_type_format_to_data_type(parser->obj_openapi));
	}
}

extern int dump(void *src, ssize_t src_bytes,
		const parser_t *const field_parser,
		const parser_t *const parser, data_t *dst, args_t *args)
{
	int rc;

	log_flag(DATA, "dump %zd byte %s object at 0x%" PRIxPTR " with parser %s(0x%" PRIxPTR ") to data 0x%" PRIxPTR,
		 (src_bytes == NO_VAL ? -1 : src_bytes),
		 parser->obj_type_string, (uintptr_t) src, parser->type_string,
		 (uintptr_t) parser, (uintptr_t) dst);

	check_parser(parser);
	xassert(parser->model != PARSER_MODEL_ARRAY_SKIP_FIELD);
	xassert(dst && (data_get_type(dst) != DATA_TYPE_NONE));
	xassert(args->magic == MAGIC_ARGS);
	xassert((src_bytes == NO_VAL) || (src_bytes > 0));

	/*
	 * Make sure the source object is the same size since there is no
	 * way to dump value of __typeof__ as a value in C.
	 */
	xassert((src_bytes == NO_VAL) || (src_bytes == parser->size) ||
		(parser->model == PARSER_MODEL_ALIAS));

	if (args->flags & FLAG_SPEC_ONLY) {
		set_openapi_schema(dst, parser, args);
		return SLURM_SUCCESS;
	}

	if ((rc = load_prereqs(DUMPING, parser, args)))
		goto done;

	switch (parser->model) {
	case PARSER_MODEL_REMOVED:
		_dump_removed(parser, dst, args);
		rc = SLURM_SUCCESS;
		break;
	case PARSER_MODEL_FLAG_ARRAY:
		verify_parser_not_sliced(parser);
		xassert((data_get_type(dst) == DATA_TYPE_NULL) ||
			(data_get_type(dst) == DATA_TYPE_LIST));
		xassert(parser->ptr_offset == NO_VAL);

		if (data_get_type(dst) != DATA_TYPE_LIST)
			data_set_list(dst);

		rc = _dump_flag_bit_array(args, src, dst, parser);
		break;
	case PARSER_MODEL_ARRAY:
		verify_parser_not_sliced(parser);
		xassert(parser->fields);
		xassert((data_get_type(dst) == DATA_TYPE_NULL) ||
			(data_get_type(dst) == DATA_TYPE_DICT));
		/* recursively run linked parsers for each struct field */
		for (int i = 0; !rc && (i < parser->field_count); i++)
			rc = _dump_linked(args, parser, &parser->fields[i], src,
					  dst);
		break;
	case PARSER_MODEL_LIST:
		xassert(parser->list_type > DATA_PARSER_TYPE_INVALID);
		xassert(parser->list_type < DATA_PARSER_TYPE_MAX);
		verify_parser_not_sliced(parser);
		xassert((data_get_type(dst) == DATA_TYPE_NULL) ||
			(data_get_type(dst) == DATA_TYPE_LIST));
		xassert((src_bytes == NO_VAL) || (src_bytes == sizeof(list_t *)));
		xassert(!parser->dump);
		rc = _dump_list(parser, src, dst, args);
		break;
	case PARSER_MODEL_PTR:
		xassert(parser->pointer_type > DATA_PARSER_TYPE_INVALID);
		xassert(parser->pointer_type < DATA_PARSER_TYPE_MAX);
		verify_parser_not_sliced(parser);
		xassert(data_get_type(dst) == DATA_TYPE_NULL);

		rc = _dump_pointer(field_parser, parser, src, dst, args);
		break;
	case PARSER_MODEL_NT_PTR_ARRAY:
	case PARSER_MODEL_NT_ARRAY:
		xassert(parser->array_type > DATA_PARSER_TYPE_INVALID);
		xassert(parser->array_type < DATA_PARSER_TYPE_MAX);
		verify_parser_not_sliced(parser);
		xassert(data_get_type(dst) == DATA_TYPE_NULL);

		rc = _dump_nt_array(parser, src, dst, args);
		break;
	case PARSER_MODEL_SIMPLE:
	case PARSER_MODEL_COMPLEX:
		xassert(data_get_type(dst) == DATA_TYPE_NULL);
		verify_parser_not_sliced(parser);

		xassert(parser->dump != _dump_list);

		/*
		 * parser->pointer_type and parser->array_type may be set but
		 * they are only used to OpenAPI typing and are ignored here.
		 */

		if (!(rc = parser->dump(parser, src, dst, args)))
			_check_dump(parser, dst, args);
		break;
	case PARSER_MODEL_ALIAS:
		rc = dump(src, src_bytes, NULL,
			  find_parser_by_type(parser->alias_type), dst, args);
		break;
	case PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD:
	case PARSER_MODEL_ARRAY_LINKED_FIELD:
		fatal_abort("%s: link model not allowed %u",
			    __func__, parser->model);
	case PARSER_MODEL_ARRAY_SKIP_FIELD:
		fatal_abort("%s: skip model not allowed %u",
			    __func__, parser->model);
	case PARSER_MODEL_ARRAY_REMOVED_FIELD:
		fatal_abort("%s: removed model not allowed %u",
			    __func__, parser->model);
	case PARSER_MODEL_INVALID:
	case PARSER_MODEL_MAX:
		fatal_abort("%s: invalid model %u", __func__, parser->model);
	}

done:
	log_flag(DATA, "dump %zd byte %s object at 0x%" PRIxPTR " with parser %s(0x%" PRIxPTR ") to data 0x%" PRIxPTR " rc[%d]=%s",
		 (src_bytes == NO_VAL ? -1 : src_bytes),
		 parser->obj_type_string, (uintptr_t) src, parser->type_string,
		 (uintptr_t) parser, (uintptr_t) dst, rc, slurm_strerror(rc));

	return rc;
}
