/*****************************************************************************\
 *  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);
		list_args.list = list_create((ListDelF) lparser->free);
	}

	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.
		 */

		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;
}
