// This file was generated by generate-classes.
// DO NOT EDIT THIS FILE!

#include "ModelJsonWriter.h"

#include <CesiumGltf/Accessor.h>
#include <CesiumGltf/AccessorSparse.h>
#include <CesiumGltf/AccessorSparseIndices.h>
#include <CesiumGltf/AccessorSparseValues.h>
#include <CesiumGltf/Animation.h>
#include <CesiumGltf/AnimationChannel.h>
#include <CesiumGltf/AnimationChannelTarget.h>
#include <CesiumGltf/AnimationSampler.h>
#include <CesiumGltf/Asset.h>
#include <CesiumGltf/Buffer.h>
#include <CesiumGltf/BufferView.h>
#include <CesiumGltf/Camera.h>
#include <CesiumGltf/CameraOrthographic.h>
#include <CesiumGltf/CameraPerspective.h>
#include <CesiumGltf/Class.h>
#include <CesiumGltf/ClassProperty.h>
#include <CesiumGltf/ClassStatistics.h>
#include <CesiumGltf/Enum.h>
#include <CesiumGltf/EnumValue.h>
#include <CesiumGltf/ExtensionBufferExtMeshoptCompression.h>
#include <CesiumGltf/ExtensionBufferViewExtMeshoptCompression.h>
#include <CesiumGltf/ExtensionCesiumRTC.h>
#include <CesiumGltf/ExtensionCesiumTileEdges.h>
#include <CesiumGltf/ExtensionExtInstanceFeatures.h>
#include <CesiumGltf/ExtensionExtInstanceFeaturesFeatureId.h>
#include <CesiumGltf/ExtensionExtMeshFeatures.h>
#include <CesiumGltf/ExtensionExtMeshFeaturesFeatureId.h>
#include <CesiumGltf/ExtensionExtMeshFeaturesFeatureIdTexture.h>
#include <CesiumGltf/ExtensionExtMeshGpuInstancing.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataClass.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataClassProperty.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataEnum.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataEnumValue.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataPropertyAttribute.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataPropertyAttributeProperty.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataPropertyTable.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataPropertyTableProperty.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataPropertyTexture.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataPropertyTextureProperty.h>
#include <CesiumGltf/ExtensionExtStructuralMetadataSchema.h>
#include <CesiumGltf/ExtensionKhrDracoMeshCompression.h>
#include <CesiumGltf/ExtensionKhrMaterialsUnlit.h>
#include <CesiumGltf/ExtensionKhrTextureBasisu.h>
#include <CesiumGltf/ExtensionKhrTextureTransform.h>
#include <CesiumGltf/ExtensionMeshPrimitiveExtFeatureMetadata.h>
#include <CesiumGltf/ExtensionMeshPrimitiveExtStructuralMetadata.h>
#include <CesiumGltf/ExtensionModelExtFeatureMetadata.h>
#include <CesiumGltf/ExtensionModelExtStructuralMetadata.h>
#include <CesiumGltf/ExtensionModelMaxarMeshVariants.h>
#include <CesiumGltf/ExtensionModelMaxarMeshVariantsValue.h>
#include <CesiumGltf/ExtensionNodeMaxarMeshVariants.h>
#include <CesiumGltf/ExtensionNodeMaxarMeshVariantsMappingsValue.h>
#include <CesiumGltf/ExtensionTextureWebp.h>
#include <CesiumGltf/FeatureIDAttribute.h>
#include <CesiumGltf/FeatureIDTexture.h>
#include <CesiumGltf/FeatureIDs.h>
#include <CesiumGltf/FeatureTable.h>
#include <CesiumGltf/FeatureTableProperty.h>
#include <CesiumGltf/FeatureTexture.h>
#include <CesiumGltf/Image.h>
#include <CesiumGltf/Material.h>
#include <CesiumGltf/MaterialNormalTextureInfo.h>
#include <CesiumGltf/MaterialOcclusionTextureInfo.h>
#include <CesiumGltf/MaterialPBRMetallicRoughness.h>
#include <CesiumGltf/Mesh.h>
#include <CesiumGltf/MeshPrimitive.h>
#include <CesiumGltf/Model.h>
#include <CesiumGltf/Node.h>
#include <CesiumGltf/PropertyStatistics.h>
#include <CesiumGltf/Sampler.h>
#include <CesiumGltf/Scene.h>
#include <CesiumGltf/Schema.h>
#include <CesiumGltf/Skin.h>
#include <CesiumGltf/Statistics.h>
#include <CesiumGltf/Texture.h>
#include <CesiumGltf/TextureAccessor.h>
#include <CesiumGltf/TextureInfo.h>
#include <CesiumJsonWriter/ExtensionWriterContext.h>
#include <CesiumJsonWriter/JsonObjectWriter.h>
#include <CesiumJsonWriter/JsonWriter.h>
#include <CesiumJsonWriter/writeJsonExtensions.h>
#include <CesiumUtility/JsonValue.h>

namespace CesiumGltfWriter {

namespace {

void writeJson(
    const CesiumGltf::ExtensionCesiumRTC& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionCesiumTileEdges& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionModelExtFeatureMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionMeshPrimitiveExtFeatureMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtInstanceFeatures& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtMeshFeatures& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtMeshGpuInstancing& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionBufferExtMeshoptCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionBufferViewExtMeshoptCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionModelExtStructuralMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionMeshPrimitiveExtStructuralMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionKhrDracoMeshCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionKhrMaterialsUnlit& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionKhrTextureBasisu& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionModelMaxarMeshVariants& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionNodeMaxarMeshVariants& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionKhrTextureTransform& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionTextureWebp& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionNodeMaxarMeshVariantsMappingsValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionModelMaxarMeshVariantsValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyAttribute& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyAttributeProperty&
        obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTextureProperty&
        obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::TextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTable& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTableProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataSchema& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataEnum& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataEnumValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataClass& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataClassProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtMeshFeaturesFeatureId& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtMeshFeaturesFeatureIdTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ExtensionExtInstanceFeaturesFeatureId& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::FeatureIDTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::TextureAccessor& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::FeatureIDAttribute& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::FeatureIDs& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::FeatureTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::FeatureTable& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::FeatureTableProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Statistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ClassStatistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::PropertyStatistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Schema& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Enum& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::EnumValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Class& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::ClassProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Model& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Texture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Skin& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Scene& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Sampler& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Node& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Mesh& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::MeshPrimitive& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Material& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::MaterialOcclusionTextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::MaterialNormalTextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::MaterialPBRMetallicRoughness& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Image& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Camera& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::CameraPerspective& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::CameraOrthographic& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::BufferView& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Buffer& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Asset& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Animation& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::AnimationSampler& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::AnimationChannel& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::AnimationChannelTarget& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::Accessor& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::AccessorSparse& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::AccessorSparseValues& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

void writeJson(
    const CesiumGltf::AccessorSparseIndices& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

// Forward declaration to avoid circular dependency since some properties
// are vector of unordered_map and others are unordered_map of vector
template <typename T>
[[maybe_unused]] void writeJson(
    const std::vector<T>& list,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context);

[[maybe_unused]] void writeJson(
    const std::string& str,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  jsonWriter.String(str);
}

[[maybe_unused]] void writeJson(
    double val,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  jsonWriter.Double(val);
}

[[maybe_unused]] void writeJson(
    bool val,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  jsonWriter.Bool(val);
}

[[maybe_unused]] void writeJson(
    int64_t val,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  jsonWriter.Int64(val);
}

[[maybe_unused]] void writeJson(
    int32_t val,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  jsonWriter.Int64(val);
}

[[maybe_unused]] void writeJson(
    const CesiumUtility::JsonValue::Object& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  jsonWriter.StartObject();
  for (const auto& item : obj) {
    jsonWriter.Key(item.first);
    CesiumJsonWriter::writeJsonValue(item.second, jsonWriter);
  }
  jsonWriter.EndObject();
}

[[maybe_unused]] void writeJson(
    const CesiumUtility::JsonValue& value,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& /* context */) {
  CesiumJsonWriter::writeJsonValue(value, jsonWriter);
}

template <typename T>
[[maybe_unused]] void writeJson(
    const std::unordered_map<std::string, T>& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();
  for (const auto& item : obj) {
    jsonWriter.Key(item.first);
    writeJson(item.second, jsonWriter, context);
  }
  jsonWriter.EndObject();
}

template <typename T>
[[maybe_unused]] void writeJson(
    const std::vector<T>& list,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartArray();
  for (const T& item : list) {
    writeJson(item, jsonWriter, context);
  }
  jsonWriter.EndArray();
}

template <typename T>
[[maybe_unused]] void writeJson(
    const std::optional<T>& val,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  if (val.has_value()) {
    writeJson(*val, jsonWriter, context);
  } else {
    jsonWriter.Null();
  }
}

template <typename T>
void writeExtensibleObject(
    const T& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {

  if (!obj.extensions.empty()) {
    jsonWriter.Key("extensions");
    writeJsonExtensions(obj, jsonWriter, context);
  }

  if (!obj.extras.empty()) {
    jsonWriter.Key("extras");
    writeJson(obj.extras, jsonWriter, context);
  }
}

template <typename T>
void writeNamedObject(
    const T& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {

  if (!obj.name.empty()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);
}

template <typename T>
void writeTextureInfo(
    const T& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {

  if (obj.index > -1) {
    jsonWriter.Key("index");
    writeJson(obj.index, jsonWriter, context);
  }

  if (obj.texCoord != 0) {
    jsonWriter.Key("texCoord");
    writeJson(obj.texCoord, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);
}

void writeJson(
    const CesiumGltf::ExtensionCesiumRTC& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.center.empty()) {
    jsonWriter.Key("center");
    writeJson(obj.center, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionCesiumTileEdges& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.left > -1) {
    jsonWriter.Key("left");
    writeJson(obj.left, jsonWriter, context);
  }

  if (obj.bottom > -1) {
    jsonWriter.Key("bottom");
    writeJson(obj.bottom, jsonWriter, context);
  }

  if (obj.right > -1) {
    jsonWriter.Key("right");
    writeJson(obj.right, jsonWriter, context);
  }

  if (obj.top > -1) {
    jsonWriter.Key("top");
    writeJson(obj.top, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionModelExtFeatureMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.schema.has_value()) {
    jsonWriter.Key("schema");
    writeJson(obj.schema, jsonWriter, context);
  }

  if (obj.schemaUri.has_value()) {
    jsonWriter.Key("schemaUri");
    writeJson(obj.schemaUri, jsonWriter, context);
  }

  if (obj.statistics.has_value()) {
    jsonWriter.Key("statistics");
    writeJson(obj.statistics, jsonWriter, context);
  }

  if (!obj.featureTables.empty()) {
    jsonWriter.Key("featureTables");
    writeJson(obj.featureTables, jsonWriter, context);
  }

  if (!obj.featureTextures.empty()) {
    jsonWriter.Key("featureTextures");
    writeJson(obj.featureTextures, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionMeshPrimitiveExtFeatureMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.featureIdAttributes.empty()) {
    jsonWriter.Key("featureIdAttributes");
    writeJson(obj.featureIdAttributes, jsonWriter, context);
  }

  if (!obj.featureIdTextures.empty()) {
    jsonWriter.Key("featureIdTextures");
    writeJson(obj.featureIdTextures, jsonWriter, context);
  }

  if (!obj.featureTextures.empty()) {
    jsonWriter.Key("featureTextures");
    writeJson(obj.featureTextures, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtInstanceFeatures& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.featureIds.empty()) {
    jsonWriter.Key("featureIds");
    writeJson(obj.featureIds, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtMeshFeatures& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.featureIds.empty()) {
    jsonWriter.Key("featureIds");
    writeJson(obj.featureIds, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtMeshGpuInstancing& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.attributes.empty()) {
    jsonWriter.Key("attributes");
    writeJson(obj.attributes, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionBufferExtMeshoptCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.fallback != false) {
    jsonWriter.Key("fallback");
    writeJson(obj.fallback, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionBufferViewExtMeshoptCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.buffer > -1) {
    jsonWriter.Key("buffer");
    writeJson(obj.buffer, jsonWriter, context);
  }

  jsonWriter.Key("byteOffset");
  writeJson(obj.byteOffset, jsonWriter, context);

  jsonWriter.Key("byteLength");
  writeJson(obj.byteLength, jsonWriter, context);

  jsonWriter.Key("byteStride");
  writeJson(obj.byteStride, jsonWriter, context);

  jsonWriter.Key("count");
  writeJson(obj.count, jsonWriter, context);

  jsonWriter.Key("mode");
  writeJson(obj.mode, jsonWriter, context);

  if (obj.filter !=
      CesiumGltf::ExtensionBufferViewExtMeshoptCompression::Filter::NONE) {
    jsonWriter.Key("filter");
    writeJson(obj.filter, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionModelExtStructuralMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.schema.has_value()) {
    jsonWriter.Key("schema");
    writeJson(obj.schema, jsonWriter, context);
  }

  if (obj.schemaUri.has_value()) {
    jsonWriter.Key("schemaUri");
    writeJson(obj.schemaUri, jsonWriter, context);
  }

  if (!obj.propertyTables.empty()) {
    jsonWriter.Key("propertyTables");
    writeJson(obj.propertyTables, jsonWriter, context);
  }

  if (!obj.propertyTextures.empty()) {
    jsonWriter.Key("propertyTextures");
    writeJson(obj.propertyTextures, jsonWriter, context);
  }

  if (!obj.propertyAttributes.empty()) {
    jsonWriter.Key("propertyAttributes");
    writeJson(obj.propertyAttributes, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionMeshPrimitiveExtStructuralMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.propertyTextures.empty()) {
    jsonWriter.Key("propertyTextures");
    writeJson(obj.propertyTextures, jsonWriter, context);
  }

  if (!obj.propertyAttributes.empty()) {
    jsonWriter.Key("propertyAttributes");
    writeJson(obj.propertyAttributes, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionKhrDracoMeshCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.bufferView > -1) {
    jsonWriter.Key("bufferView");
    writeJson(obj.bufferView, jsonWriter, context);
  }

  if (!obj.attributes.empty()) {
    jsonWriter.Key("attributes");
    writeJson(obj.attributes, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionKhrMaterialsUnlit& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionKhrTextureBasisu& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.source > -1) {
    jsonWriter.Key("source");
    writeJson(obj.source, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionModelMaxarMeshVariants& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.defaultProperty > -1) {
    jsonWriter.Key("default");
    writeJson(obj.defaultProperty, jsonWriter, context);
  }

  if (!obj.variants.empty()) {
    jsonWriter.Key("variants");
    writeJson(obj.variants, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionNodeMaxarMeshVariants& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.mappings.empty()) {
    jsonWriter.Key("mappings");
    writeJson(obj.mappings, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionKhrTextureTransform& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  static const std::vector<double> offsetDefault = {0, 0};
  if (obj.offset != offsetDefault) {
    jsonWriter.Key("offset");
    writeJson(obj.offset, jsonWriter, context);
  }

  if (obj.rotation != 0) {
    jsonWriter.Key("rotation");
    writeJson(obj.rotation, jsonWriter, context);
  }

  static const std::vector<double> scaleDefault = {1, 1};
  if (obj.scale != scaleDefault) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  if (obj.texCoord.has_value()) {
    jsonWriter.Key("texCoord");
    writeJson(obj.texCoord, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionTextureWebp& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.source > -1) {
    jsonWriter.Key("source");
    writeJson(obj.source, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionNodeMaxarMeshVariantsMappingsValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.variants.empty()) {
    jsonWriter.Key("variants");
    writeJson(obj.variants, jsonWriter, context);
  }

  if (obj.mesh > -1) {
    jsonWriter.Key("mesh");
    writeJson(obj.mesh, jsonWriter, context);
  }

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionModelMaxarMeshVariantsValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("name");
  writeJson(obj.name, jsonWriter, context);

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyAttribute& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  jsonWriter.Key("class");
  writeJson(obj.classProperty, jsonWriter, context);

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyAttributeProperty&
        obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("attribute");
  writeJson(obj.attribute, jsonWriter, context);

  if (obj.offset.has_value()) {
    jsonWriter.Key("offset");
    writeJson(obj.offset, jsonWriter, context);
  }

  if (obj.scale.has_value()) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  if (obj.max.has_value()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (obj.min.has_value()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  jsonWriter.Key("class");
  writeJson(obj.classProperty, jsonWriter, context);

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTextureProperty&
        obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  static const std::vector<int64_t> channelsDefault = {0};
  if (obj.channels != channelsDefault) {
    jsonWriter.Key("channels");
    writeJson(obj.channels, jsonWriter, context);
  }

  if (obj.offset.has_value()) {
    jsonWriter.Key("offset");
    writeJson(obj.offset, jsonWriter, context);
  }

  if (obj.scale.has_value()) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  if (obj.max.has_value()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (obj.min.has_value()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  writeTextureInfo(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::TextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  writeTextureInfo(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTable& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  jsonWriter.Key("class");
  writeJson(obj.classProperty, jsonWriter, context);

  jsonWriter.Key("count");
  writeJson(obj.count, jsonWriter, context);

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTableProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.values > -1) {
    jsonWriter.Key("values");
    writeJson(obj.values, jsonWriter, context);
  }

  if (obj.arrayOffsets > -1) {
    jsonWriter.Key("arrayOffsets");
    writeJson(obj.arrayOffsets, jsonWriter, context);
  }

  if (obj.stringOffsets > -1) {
    jsonWriter.Key("stringOffsets");
    writeJson(obj.stringOffsets, jsonWriter, context);
  }

  if (obj.arrayOffsetType !=
      CesiumGltf::ExtensionExtStructuralMetadataPropertyTableProperty::
          ArrayOffsetType::UINT32) {
    jsonWriter.Key("arrayOffsetType");
    writeJson(obj.arrayOffsetType, jsonWriter, context);
  }

  if (obj.stringOffsetType !=
      CesiumGltf::ExtensionExtStructuralMetadataPropertyTableProperty::
          StringOffsetType::UINT32) {
    jsonWriter.Key("stringOffsetType");
    writeJson(obj.stringOffsetType, jsonWriter, context);
  }

  if (obj.offset.has_value()) {
    jsonWriter.Key("offset");
    writeJson(obj.offset, jsonWriter, context);
  }

  if (obj.scale.has_value()) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  if (obj.max.has_value()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (obj.min.has_value()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataSchema& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("id");
  writeJson(obj.id, jsonWriter, context);

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  if (obj.version.has_value()) {
    jsonWriter.Key("version");
    writeJson(obj.version, jsonWriter, context);
  }

  if (!obj.classes.empty()) {
    jsonWriter.Key("classes");
    writeJson(obj.classes, jsonWriter, context);
  }

  if (!obj.enums.empty()) {
    jsonWriter.Key("enums");
    writeJson(obj.enums, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataEnum& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  if (obj.valueType !=
      CesiumGltf::ExtensionExtStructuralMetadataEnum::ValueType::UINT16) {
    jsonWriter.Key("valueType");
    writeJson(obj.valueType, jsonWriter, context);
  }

  if (!obj.values.empty()) {
    jsonWriter.Key("values");
    writeJson(obj.values, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataEnumValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("name");
  writeJson(obj.name, jsonWriter, context);

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  jsonWriter.Key("value");
  writeJson(obj.value, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataClass& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtStructuralMetadataClassProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  jsonWriter.Key("type");
  writeJson(obj.type, jsonWriter, context);

  if (obj.componentType.has_value()) {
    jsonWriter.Key("componentType");
    writeJson(obj.componentType, jsonWriter, context);
  }

  if (obj.enumType.has_value()) {
    jsonWriter.Key("enumType");
    writeJson(obj.enumType, jsonWriter, context);
  }

  if (obj.array != false) {
    jsonWriter.Key("array");
    writeJson(obj.array, jsonWriter, context);
  }

  if (obj.count.has_value()) {
    jsonWriter.Key("count");
    writeJson(obj.count, jsonWriter, context);
  }

  if (obj.normalized != false) {
    jsonWriter.Key("normalized");
    writeJson(obj.normalized, jsonWriter, context);
  }

  if (obj.offset.has_value()) {
    jsonWriter.Key("offset");
    writeJson(obj.offset, jsonWriter, context);
  }

  if (obj.scale.has_value()) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  if (obj.max.has_value()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (obj.min.has_value()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  if (obj.required != false) {
    jsonWriter.Key("required");
    writeJson(obj.required, jsonWriter, context);
  }

  if (obj.noData.has_value()) {
    jsonWriter.Key("noData");
    writeJson(obj.noData, jsonWriter, context);
  }

  if (obj.defaultProperty.has_value()) {
    jsonWriter.Key("default");
    writeJson(obj.defaultProperty, jsonWriter, context);
  }

  if (obj.semantic.has_value()) {
    jsonWriter.Key("semantic");
    writeJson(obj.semantic, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtMeshFeaturesFeatureId& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("featureCount");
  writeJson(obj.featureCount, jsonWriter, context);

  if (obj.nullFeatureId.has_value()) {
    jsonWriter.Key("nullFeatureId");
    writeJson(obj.nullFeatureId, jsonWriter, context);
  }

  if (obj.label.has_value()) {
    jsonWriter.Key("label");
    writeJson(obj.label, jsonWriter, context);
  }

  if (obj.attribute.has_value()) {
    jsonWriter.Key("attribute");
    writeJson(obj.attribute, jsonWriter, context);
  }

  if (obj.texture.has_value()) {
    jsonWriter.Key("texture");
    writeJson(obj.texture, jsonWriter, context);
  }

  if (obj.propertyTable.has_value()) {
    jsonWriter.Key("propertyTable");
    writeJson(obj.propertyTable, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtMeshFeaturesFeatureIdTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  static const std::vector<int64_t> channelsDefault = {0};
  if (obj.channels != channelsDefault) {
    jsonWriter.Key("channels");
    writeJson(obj.channels, jsonWriter, context);
  }

  writeTextureInfo(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ExtensionExtInstanceFeaturesFeatureId& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("featureCount");
  writeJson(obj.featureCount, jsonWriter, context);

  if (obj.nullFeatureId.has_value()) {
    jsonWriter.Key("nullFeatureId");
    writeJson(obj.nullFeatureId, jsonWriter, context);
  }

  if (obj.label.has_value()) {
    jsonWriter.Key("label");
    writeJson(obj.label, jsonWriter, context);
  }

  if (obj.attribute.has_value()) {
    jsonWriter.Key("attribute");
    writeJson(obj.attribute, jsonWriter, context);
  }

  if (obj.propertyTable.has_value()) {
    jsonWriter.Key("propertyTable");
    writeJson(obj.propertyTable, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::FeatureIDTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("featureTable");
  writeJson(obj.featureTable, jsonWriter, context);

  jsonWriter.Key("featureIds");
  writeJson(obj.featureIds, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::TextureAccessor& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("channels");
  writeJson(obj.channels, jsonWriter, context);

  jsonWriter.Key("texture");
  writeJson(obj.texture, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::FeatureIDAttribute& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("featureTable");
  writeJson(obj.featureTable, jsonWriter, context);

  jsonWriter.Key("featureIds");
  writeJson(obj.featureIds, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::FeatureIDs& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.attribute.has_value()) {
    jsonWriter.Key("attribute");
    writeJson(obj.attribute, jsonWriter, context);
  }

  if (obj.constant != 0) {
    jsonWriter.Key("constant");
    writeJson(obj.constant, jsonWriter, context);
  }

  if (obj.divisor != 0) {
    jsonWriter.Key("divisor");
    writeJson(obj.divisor, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::FeatureTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("class");
  writeJson(obj.classProperty, jsonWriter, context);

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::FeatureTable& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.classProperty.has_value()) {
    jsonWriter.Key("class");
    writeJson(obj.classProperty, jsonWriter, context);
  }

  jsonWriter.Key("count");
  writeJson(obj.count, jsonWriter, context);

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::FeatureTableProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.bufferView > -1) {
    jsonWriter.Key("bufferView");
    writeJson(obj.bufferView, jsonWriter, context);
  }

  if (obj.offsetType != CesiumGltf::FeatureTableProperty::OffsetType::UINT32) {
    jsonWriter.Key("offsetType");
    writeJson(obj.offsetType, jsonWriter, context);
  }

  if (obj.arrayOffsetBufferView > -1) {
    jsonWriter.Key("arrayOffsetBufferView");
    writeJson(obj.arrayOffsetBufferView, jsonWriter, context);
  }

  if (obj.stringOffsetBufferView > -1) {
    jsonWriter.Key("stringOffsetBufferView");
    writeJson(obj.stringOffsetBufferView, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Statistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.classes.empty()) {
    jsonWriter.Key("classes");
    writeJson(obj.classes, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ClassStatistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.count.has_value()) {
    jsonWriter.Key("count");
    writeJson(obj.count, jsonWriter, context);
  }

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::PropertyStatistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.min.has_value()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  if (obj.max.has_value()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (obj.mean.has_value()) {
    jsonWriter.Key("mean");
    writeJson(obj.mean, jsonWriter, context);
  }

  if (obj.median.has_value()) {
    jsonWriter.Key("median");
    writeJson(obj.median, jsonWriter, context);
  }

  if (obj.standardDeviation.has_value()) {
    jsonWriter.Key("standardDeviation");
    writeJson(obj.standardDeviation, jsonWriter, context);
  }

  if (obj.variance.has_value()) {
    jsonWriter.Key("variance");
    writeJson(obj.variance, jsonWriter, context);
  }

  if (obj.sum.has_value()) {
    jsonWriter.Key("sum");
    writeJson(obj.sum, jsonWriter, context);
  }

  if (!obj.occurrences.empty()) {
    jsonWriter.Key("occurrences");
    writeJson(obj.occurrences, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Schema& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  if (obj.version.has_value()) {
    jsonWriter.Key("version");
    writeJson(obj.version, jsonWriter, context);
  }

  if (!obj.classes.empty()) {
    jsonWriter.Key("classes");
    writeJson(obj.classes, jsonWriter, context);
  }

  if (!obj.enums.empty()) {
    jsonWriter.Key("enums");
    writeJson(obj.enums, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Enum& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  if (obj.valueType != CesiumGltf::Enum::ValueType::UINT16) {
    jsonWriter.Key("valueType");
    writeJson(obj.valueType, jsonWriter, context);
  }

  if (!obj.values.empty()) {
    jsonWriter.Key("values");
    writeJson(obj.values, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::EnumValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("name");
  writeJson(obj.name, jsonWriter, context);

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  jsonWriter.Key("value");
  writeJson(obj.value, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Class& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  if (!obj.properties.empty()) {
    jsonWriter.Key("properties");
    writeJson(obj.properties, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::ClassProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.name.has_value()) {
    jsonWriter.Key("name");
    writeJson(obj.name, jsonWriter, context);
  }

  if (obj.description.has_value()) {
    jsonWriter.Key("description");
    writeJson(obj.description, jsonWriter, context);
  }

  jsonWriter.Key("type");
  writeJson(obj.type, jsonWriter, context);

  if (obj.enumType.has_value()) {
    jsonWriter.Key("enumType");
    writeJson(obj.enumType, jsonWriter, context);
  }

  if (obj.componentType.has_value()) {
    jsonWriter.Key("componentType");
    writeJson(obj.componentType, jsonWriter, context);
  }

  if (obj.componentCount.has_value()) {
    jsonWriter.Key("componentCount");
    writeJson(obj.componentCount, jsonWriter, context);
  }

  if (obj.normalized != false) {
    jsonWriter.Key("normalized");
    writeJson(obj.normalized, jsonWriter, context);
  }

  if (obj.max.has_value()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (obj.min.has_value()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  if (obj.defaultProperty.has_value()) {
    jsonWriter.Key("default");
    writeJson(obj.defaultProperty, jsonWriter, context);
  }

  if (obj.optional != false) {
    jsonWriter.Key("optional");
    writeJson(obj.optional, jsonWriter, context);
  }

  if (obj.semantic.has_value()) {
    jsonWriter.Key("semantic");
    writeJson(obj.semantic, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Model& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.extensionsUsed.empty()) {
    jsonWriter.Key("extensionsUsed");
    writeJson(obj.extensionsUsed, jsonWriter, context);
  }

  if (!obj.extensionsRequired.empty()) {
    jsonWriter.Key("extensionsRequired");
    writeJson(obj.extensionsRequired, jsonWriter, context);
  }

  if (!obj.accessors.empty()) {
    jsonWriter.Key("accessors");
    writeJson(obj.accessors, jsonWriter, context);
  }

  if (!obj.animations.empty()) {
    jsonWriter.Key("animations");
    writeJson(obj.animations, jsonWriter, context);
  }

  jsonWriter.Key("asset");
  writeJson(obj.asset, jsonWriter, context);

  if (!obj.buffers.empty()) {
    jsonWriter.Key("buffers");
    writeJson(obj.buffers, jsonWriter, context);
  }

  if (!obj.bufferViews.empty()) {
    jsonWriter.Key("bufferViews");
    writeJson(obj.bufferViews, jsonWriter, context);
  }

  if (!obj.cameras.empty()) {
    jsonWriter.Key("cameras");
    writeJson(obj.cameras, jsonWriter, context);
  }

  if (!obj.images.empty()) {
    jsonWriter.Key("images");
    writeJson(obj.images, jsonWriter, context);
  }

  if (!obj.materials.empty()) {
    jsonWriter.Key("materials");
    writeJson(obj.materials, jsonWriter, context);
  }

  if (!obj.meshes.empty()) {
    jsonWriter.Key("meshes");
    writeJson(obj.meshes, jsonWriter, context);
  }

  if (!obj.nodes.empty()) {
    jsonWriter.Key("nodes");
    writeJson(obj.nodes, jsonWriter, context);
  }

  if (!obj.samplers.empty()) {
    jsonWriter.Key("samplers");
    writeJson(obj.samplers, jsonWriter, context);
  }

  if (obj.scene > -1) {
    jsonWriter.Key("scene");
    writeJson(obj.scene, jsonWriter, context);
  }

  if (!obj.scenes.empty()) {
    jsonWriter.Key("scenes");
    writeJson(obj.scenes, jsonWriter, context);
  }

  if (!obj.skins.empty()) {
    jsonWriter.Key("skins");
    writeJson(obj.skins, jsonWriter, context);
  }

  if (!obj.textures.empty()) {
    jsonWriter.Key("textures");
    writeJson(obj.textures, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Texture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.sampler > -1) {
    jsonWriter.Key("sampler");
    writeJson(obj.sampler, jsonWriter, context);
  }

  if (obj.source > -1) {
    jsonWriter.Key("source");
    writeJson(obj.source, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Skin& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.inverseBindMatrices > -1) {
    jsonWriter.Key("inverseBindMatrices");
    writeJson(obj.inverseBindMatrices, jsonWriter, context);
  }

  if (obj.skeleton > -1) {
    jsonWriter.Key("skeleton");
    writeJson(obj.skeleton, jsonWriter, context);
  }

  if (!obj.joints.empty()) {
    jsonWriter.Key("joints");
    writeJson(obj.joints, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Scene& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.nodes.empty()) {
    jsonWriter.Key("nodes");
    writeJson(obj.nodes, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Sampler& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.magFilter.has_value()) {
    jsonWriter.Key("magFilter");
    writeJson(obj.magFilter, jsonWriter, context);
  }

  if (obj.minFilter.has_value()) {
    jsonWriter.Key("minFilter");
    writeJson(obj.minFilter, jsonWriter, context);
  }

  if (obj.wrapS != CesiumGltf::Sampler::WrapS::REPEAT) {
    jsonWriter.Key("wrapS");
    writeJson(obj.wrapS, jsonWriter, context);
  }

  if (obj.wrapT != CesiumGltf::Sampler::WrapT::REPEAT) {
    jsonWriter.Key("wrapT");
    writeJson(obj.wrapT, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Node& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.camera > -1) {
    jsonWriter.Key("camera");
    writeJson(obj.camera, jsonWriter, context);
  }

  if (!obj.children.empty()) {
    jsonWriter.Key("children");
    writeJson(obj.children, jsonWriter, context);
  }

  if (obj.skin > -1) {
    jsonWriter.Key("skin");
    writeJson(obj.skin, jsonWriter, context);
  }

  static const std::vector<double> matrixDefault =
      {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
  if (obj.matrix != matrixDefault) {
    jsonWriter.Key("matrix");
    writeJson(obj.matrix, jsonWriter, context);
  }

  if (obj.mesh > -1) {
    jsonWriter.Key("mesh");
    writeJson(obj.mesh, jsonWriter, context);
  }

  static const std::vector<double> rotationDefault = {0, 0, 0, 1};
  if (obj.rotation != rotationDefault) {
    jsonWriter.Key("rotation");
    writeJson(obj.rotation, jsonWriter, context);
  }

  static const std::vector<double> scaleDefault = {1, 1, 1};
  if (obj.scale != scaleDefault) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  static const std::vector<double> translationDefault = {0, 0, 0};
  if (obj.translation != translationDefault) {
    jsonWriter.Key("translation");
    writeJson(obj.translation, jsonWriter, context);
  }

  if (!obj.weights.empty()) {
    jsonWriter.Key("weights");
    writeJson(obj.weights, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Mesh& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.primitives.empty()) {
    jsonWriter.Key("primitives");
    writeJson(obj.primitives, jsonWriter, context);
  }

  if (!obj.weights.empty()) {
    jsonWriter.Key("weights");
    writeJson(obj.weights, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::MeshPrimitive& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.attributes.empty()) {
    jsonWriter.Key("attributes");
    writeJson(obj.attributes, jsonWriter, context);
  }

  if (obj.indices > -1) {
    jsonWriter.Key("indices");
    writeJson(obj.indices, jsonWriter, context);
  }

  if (obj.material > -1) {
    jsonWriter.Key("material");
    writeJson(obj.material, jsonWriter, context);
  }

  if (obj.mode != CesiumGltf::MeshPrimitive::Mode::TRIANGLES) {
    jsonWriter.Key("mode");
    writeJson(obj.mode, jsonWriter, context);
  }

  if (!obj.targets.empty()) {
    jsonWriter.Key("targets");
    writeJson(obj.targets, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Material& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.pbrMetallicRoughness.has_value()) {
    jsonWriter.Key("pbrMetallicRoughness");
    writeJson(obj.pbrMetallicRoughness, jsonWriter, context);
  }

  if (obj.normalTexture.has_value()) {
    jsonWriter.Key("normalTexture");
    writeJson(obj.normalTexture, jsonWriter, context);
  }

  if (obj.occlusionTexture.has_value()) {
    jsonWriter.Key("occlusionTexture");
    writeJson(obj.occlusionTexture, jsonWriter, context);
  }

  if (obj.emissiveTexture.has_value()) {
    jsonWriter.Key("emissiveTexture");
    writeJson(obj.emissiveTexture, jsonWriter, context);
  }

  static const std::vector<double> emissiveFactorDefault = {0, 0, 0};
  if (obj.emissiveFactor != emissiveFactorDefault) {
    jsonWriter.Key("emissiveFactor");
    writeJson(obj.emissiveFactor, jsonWriter, context);
  }

  if (obj.alphaMode != CesiumGltf::Material::AlphaMode::OPAQUE) {
    jsonWriter.Key("alphaMode");
    writeJson(obj.alphaMode, jsonWriter, context);
  }

  if (obj.alphaCutoff != 0.5) {
    jsonWriter.Key("alphaCutoff");
    writeJson(obj.alphaCutoff, jsonWriter, context);
  }

  if (obj.doubleSided != false) {
    jsonWriter.Key("doubleSided");
    writeJson(obj.doubleSided, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::MaterialOcclusionTextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.strength != 1) {
    jsonWriter.Key("strength");
    writeJson(obj.strength, jsonWriter, context);
  }

  writeTextureInfo(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::MaterialNormalTextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.scale != 1) {
    jsonWriter.Key("scale");
    writeJson(obj.scale, jsonWriter, context);
  }

  writeTextureInfo(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::MaterialPBRMetallicRoughness& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  static const std::vector<double> baseColorFactorDefault = {1, 1, 1, 1};
  if (obj.baseColorFactor != baseColorFactorDefault) {
    jsonWriter.Key("baseColorFactor");
    writeJson(obj.baseColorFactor, jsonWriter, context);
  }

  if (obj.baseColorTexture.has_value()) {
    jsonWriter.Key("baseColorTexture");
    writeJson(obj.baseColorTexture, jsonWriter, context);
  }

  if (obj.metallicFactor != 1) {
    jsonWriter.Key("metallicFactor");
    writeJson(obj.metallicFactor, jsonWriter, context);
  }

  if (obj.roughnessFactor != 1) {
    jsonWriter.Key("roughnessFactor");
    writeJson(obj.roughnessFactor, jsonWriter, context);
  }

  if (obj.metallicRoughnessTexture.has_value()) {
    jsonWriter.Key("metallicRoughnessTexture");
    writeJson(obj.metallicRoughnessTexture, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Image& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.uri.has_value()) {
    jsonWriter.Key("uri");
    writeJson(obj.uri, jsonWriter, context);
  }

  if (obj.mimeType.has_value()) {
    jsonWriter.Key("mimeType");
    writeJson(obj.mimeType, jsonWriter, context);
  }

  if (obj.bufferView > -1) {
    jsonWriter.Key("bufferView");
    writeJson(obj.bufferView, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Camera& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.orthographic.has_value()) {
    jsonWriter.Key("orthographic");
    writeJson(obj.orthographic, jsonWriter, context);
  }

  if (obj.perspective.has_value()) {
    jsonWriter.Key("perspective");
    writeJson(obj.perspective, jsonWriter, context);
  }

  jsonWriter.Key("type");
  writeJson(obj.type, jsonWriter, context);

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::CameraPerspective& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.aspectRatio.has_value()) {
    jsonWriter.Key("aspectRatio");
    writeJson(obj.aspectRatio, jsonWriter, context);
  }

  jsonWriter.Key("yfov");
  writeJson(obj.yfov, jsonWriter, context);

  if (obj.zfar.has_value()) {
    jsonWriter.Key("zfar");
    writeJson(obj.zfar, jsonWriter, context);
  }

  jsonWriter.Key("znear");
  writeJson(obj.znear, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::CameraOrthographic& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("xmag");
  writeJson(obj.xmag, jsonWriter, context);

  jsonWriter.Key("ymag");
  writeJson(obj.ymag, jsonWriter, context);

  jsonWriter.Key("zfar");
  writeJson(obj.zfar, jsonWriter, context);

  jsonWriter.Key("znear");
  writeJson(obj.znear, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::BufferView& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.buffer > -1) {
    jsonWriter.Key("buffer");
    writeJson(obj.buffer, jsonWriter, context);
  }

  jsonWriter.Key("byteOffset");
  writeJson(obj.byteOffset, jsonWriter, context);

  jsonWriter.Key("byteLength");
  writeJson(obj.byteLength, jsonWriter, context);

  if (obj.byteStride.has_value()) {
    jsonWriter.Key("byteStride");
    writeJson(obj.byteStride, jsonWriter, context);
  }

  if (obj.target.has_value()) {
    jsonWriter.Key("target");
    writeJson(obj.target, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Buffer& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.uri.has_value()) {
    jsonWriter.Key("uri");
    writeJson(obj.uri, jsonWriter, context);
  }

  jsonWriter.Key("byteLength");
  writeJson(obj.byteLength, jsonWriter, context);

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Asset& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.copyright.has_value()) {
    jsonWriter.Key("copyright");
    writeJson(obj.copyright, jsonWriter, context);
  }

  if (obj.generator.has_value()) {
    jsonWriter.Key("generator");
    writeJson(obj.generator, jsonWriter, context);
  }

  jsonWriter.Key("version");
  writeJson(obj.version, jsonWriter, context);

  if (obj.minVersion.has_value()) {
    jsonWriter.Key("minVersion");
    writeJson(obj.minVersion, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Animation& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (!obj.channels.empty()) {
    jsonWriter.Key("channels");
    writeJson(obj.channels, jsonWriter, context);
  }

  if (!obj.samplers.empty()) {
    jsonWriter.Key("samplers");
    writeJson(obj.samplers, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::AnimationSampler& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.input > -1) {
    jsonWriter.Key("input");
    writeJson(obj.input, jsonWriter, context);
  }

  if (obj.interpolation !=
      CesiumGltf::AnimationSampler::Interpolation::LINEAR) {
    jsonWriter.Key("interpolation");
    writeJson(obj.interpolation, jsonWriter, context);
  }

  if (obj.output > -1) {
    jsonWriter.Key("output");
    writeJson(obj.output, jsonWriter, context);
  }

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::AnimationChannel& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.sampler > -1) {
    jsonWriter.Key("sampler");
    writeJson(obj.sampler, jsonWriter, context);
  }

  jsonWriter.Key("target");
  writeJson(obj.target, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::AnimationChannelTarget& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.node > -1) {
    jsonWriter.Key("node");
    writeJson(obj.node, jsonWriter, context);
  }

  jsonWriter.Key("path");
  writeJson(obj.path, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::Accessor& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.bufferView > -1) {
    jsonWriter.Key("bufferView");
    writeJson(obj.bufferView, jsonWriter, context);
  }

  jsonWriter.Key("byteOffset");
  writeJson(obj.byteOffset, jsonWriter, context);

  jsonWriter.Key("componentType");
  writeJson(obj.componentType, jsonWriter, context);

  if (obj.normalized != false) {
    jsonWriter.Key("normalized");
    writeJson(obj.normalized, jsonWriter, context);
  }

  jsonWriter.Key("count");
  writeJson(obj.count, jsonWriter, context);

  jsonWriter.Key("type");
  writeJson(obj.type, jsonWriter, context);

  if (!obj.max.empty()) {
    jsonWriter.Key("max");
    writeJson(obj.max, jsonWriter, context);
  }

  if (!obj.min.empty()) {
    jsonWriter.Key("min");
    writeJson(obj.min, jsonWriter, context);
  }

  if (obj.sparse.has_value()) {
    jsonWriter.Key("sparse");
    writeJson(obj.sparse, jsonWriter, context);
  }

  writeNamedObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::AccessorSparse& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  jsonWriter.Key("count");
  writeJson(obj.count, jsonWriter, context);

  jsonWriter.Key("indices");
  writeJson(obj.indices, jsonWriter, context);

  jsonWriter.Key("values");
  writeJson(obj.values, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::AccessorSparseValues& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.bufferView > -1) {
    jsonWriter.Key("bufferView");
    writeJson(obj.bufferView, jsonWriter, context);
  }

  jsonWriter.Key("byteOffset");
  writeJson(obj.byteOffset, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

void writeJson(
    const CesiumGltf::AccessorSparseIndices& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  jsonWriter.StartObject();

  if (obj.bufferView > -1) {
    jsonWriter.Key("bufferView");
    writeJson(obj.bufferView, jsonWriter, context);
  }

  jsonWriter.Key("byteOffset");
  writeJson(obj.byteOffset, jsonWriter, context);

  jsonWriter.Key("componentType");
  writeJson(obj.componentType, jsonWriter, context);

  writeExtensibleObject(obj, jsonWriter, context);

  jsonWriter.EndObject();
}

} // namespace

void ExtensionCesiumRTCJsonWriter::write(
    const CesiumGltf::ExtensionCesiumRTC& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionCesiumTileEdgesJsonWriter::write(
    const CesiumGltf::ExtensionCesiumTileEdges& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionModelExtFeatureMetadataJsonWriter::write(
    const CesiumGltf::ExtensionModelExtFeatureMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionMeshPrimitiveExtFeatureMetadataJsonWriter::write(
    const CesiumGltf::ExtensionMeshPrimitiveExtFeatureMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtInstanceFeaturesJsonWriter::write(
    const CesiumGltf::ExtensionExtInstanceFeatures& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtMeshFeaturesJsonWriter::write(
    const CesiumGltf::ExtensionExtMeshFeatures& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtMeshGpuInstancingJsonWriter::write(
    const CesiumGltf::ExtensionExtMeshGpuInstancing& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionBufferExtMeshoptCompressionJsonWriter::write(
    const CesiumGltf::ExtensionBufferExtMeshoptCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionBufferViewExtMeshoptCompressionJsonWriter::write(
    const CesiumGltf::ExtensionBufferViewExtMeshoptCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionModelExtStructuralMetadataJsonWriter::write(
    const CesiumGltf::ExtensionModelExtStructuralMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionMeshPrimitiveExtStructuralMetadataJsonWriter::write(
    const CesiumGltf::ExtensionMeshPrimitiveExtStructuralMetadata& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionKhrDracoMeshCompressionJsonWriter::write(
    const CesiumGltf::ExtensionKhrDracoMeshCompression& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionKhrMaterialsUnlitJsonWriter::write(
    const CesiumGltf::ExtensionKhrMaterialsUnlit& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionKhrTextureBasisuJsonWriter::write(
    const CesiumGltf::ExtensionKhrTextureBasisu& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionModelMaxarMeshVariantsJsonWriter::write(
    const CesiumGltf::ExtensionModelMaxarMeshVariants& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionNodeMaxarMeshVariantsJsonWriter::write(
    const CesiumGltf::ExtensionNodeMaxarMeshVariants& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionKhrTextureTransformJsonWriter::write(
    const CesiumGltf::ExtensionKhrTextureTransform& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionTextureWebpJsonWriter::write(
    const CesiumGltf::ExtensionTextureWebp& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionNodeMaxarMeshVariantsMappingsValueJsonWriter::write(
    const CesiumGltf::ExtensionNodeMaxarMeshVariantsMappingsValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionModelMaxarMeshVariantsValueJsonWriter::write(
    const CesiumGltf::ExtensionModelMaxarMeshVariantsValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataPropertyAttributeJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyAttribute& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataPropertyAttributePropertyJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyAttributeProperty&
        obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataPropertyTextureJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataPropertyTexturePropertyJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTextureProperty&
        obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void TextureInfoJsonWriter::write(
    const CesiumGltf::TextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataPropertyTableJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTable& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataPropertyTablePropertyJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataPropertyTableProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataSchemaJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataSchema& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataEnumJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataEnum& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataEnumValueJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataEnumValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataClassJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataClass& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtStructuralMetadataClassPropertyJsonWriter::write(
    const CesiumGltf::ExtensionExtStructuralMetadataClassProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtMeshFeaturesFeatureIdJsonWriter::write(
    const CesiumGltf::ExtensionExtMeshFeaturesFeatureId& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtMeshFeaturesFeatureIdTextureJsonWriter::write(
    const CesiumGltf::ExtensionExtMeshFeaturesFeatureIdTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ExtensionExtInstanceFeaturesFeatureIdJsonWriter::write(
    const CesiumGltf::ExtensionExtInstanceFeaturesFeatureId& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void FeatureIDTextureJsonWriter::write(
    const CesiumGltf::FeatureIDTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void TextureAccessorJsonWriter::write(
    const CesiumGltf::TextureAccessor& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void FeatureIDAttributeJsonWriter::write(
    const CesiumGltf::FeatureIDAttribute& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void FeatureIDsJsonWriter::write(
    const CesiumGltf::FeatureIDs& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void FeatureTextureJsonWriter::write(
    const CesiumGltf::FeatureTexture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void FeatureTableJsonWriter::write(
    const CesiumGltf::FeatureTable& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void FeatureTablePropertyJsonWriter::write(
    const CesiumGltf::FeatureTableProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void StatisticsJsonWriter::write(
    const CesiumGltf::Statistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ClassStatisticsJsonWriter::write(
    const CesiumGltf::ClassStatistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void PropertyStatisticsJsonWriter::write(
    const CesiumGltf::PropertyStatistics& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void SchemaJsonWriter::write(
    const CesiumGltf::Schema& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void EnumJsonWriter::write(
    const CesiumGltf::Enum& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void EnumValueJsonWriter::write(
    const CesiumGltf::EnumValue& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ClassJsonWriter::write(
    const CesiumGltf::Class& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ClassPropertyJsonWriter::write(
    const CesiumGltf::ClassProperty& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ModelJsonWriter::write(
    const CesiumGltf::Model& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void TextureJsonWriter::write(
    const CesiumGltf::Texture& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void SkinJsonWriter::write(
    const CesiumGltf::Skin& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void SceneJsonWriter::write(
    const CesiumGltf::Scene& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void SamplerJsonWriter::write(
    const CesiumGltf::Sampler& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void NodeJsonWriter::write(
    const CesiumGltf::Node& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void MeshJsonWriter::write(
    const CesiumGltf::Mesh& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void MeshPrimitiveJsonWriter::write(
    const CesiumGltf::MeshPrimitive& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void MaterialJsonWriter::write(
    const CesiumGltf::Material& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void MaterialOcclusionTextureInfoJsonWriter::write(
    const CesiumGltf::MaterialOcclusionTextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void MaterialNormalTextureInfoJsonWriter::write(
    const CesiumGltf::MaterialNormalTextureInfo& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void MaterialPBRMetallicRoughnessJsonWriter::write(
    const CesiumGltf::MaterialPBRMetallicRoughness& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void ImageJsonWriter::write(
    const CesiumGltf::Image& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void CameraJsonWriter::write(
    const CesiumGltf::Camera& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void CameraPerspectiveJsonWriter::write(
    const CesiumGltf::CameraPerspective& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void CameraOrthographicJsonWriter::write(
    const CesiumGltf::CameraOrthographic& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void BufferViewJsonWriter::write(
    const CesiumGltf::BufferView& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void BufferJsonWriter::write(
    const CesiumGltf::Buffer& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AssetJsonWriter::write(
    const CesiumGltf::Asset& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AnimationJsonWriter::write(
    const CesiumGltf::Animation& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AnimationSamplerJsonWriter::write(
    const CesiumGltf::AnimationSampler& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AnimationChannelJsonWriter::write(
    const CesiumGltf::AnimationChannel& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AnimationChannelTargetJsonWriter::write(
    const CesiumGltf::AnimationChannelTarget& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AccessorJsonWriter::write(
    const CesiumGltf::Accessor& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AccessorSparseJsonWriter::write(
    const CesiumGltf::AccessorSparse& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AccessorSparseValuesJsonWriter::write(
    const CesiumGltf::AccessorSparseValues& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

void AccessorSparseIndicesJsonWriter::write(
    const CesiumGltf::AccessorSparseIndices& obj,
    CesiumJsonWriter::JsonWriter& jsonWriter,
    const CesiumJsonWriter::ExtensionWriterContext& context) {
  writeJson(obj, jsonWriter, context);
}

} // namespace CesiumGltfWriter
