private object? CreateObject()

in src/Elastic.Apm/Libraries/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs [374:535]


		private object? CreateObject(JsonReader reader, Type? objectType, JsonContract? contract, JsonProperty? member,
			JsonContainerContract? containerContract, JsonProperty? containerMember, object? existingValue
		)
		{
			string? id;
			var resolvedObjectType = objectType;

			if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.Ignore)
			{
				// don't look for metadata properties
				reader.ReadAndAssert();
				id = null;
			}
			else if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead)
			{
				if (!(reader is JTokenReader tokenReader))
				{
					var t = JToken.ReadFrom(reader);
					tokenReader = (JTokenReader)t.CreateReader();
					tokenReader.Culture = reader.Culture;
					tokenReader.DateFormatString = reader.DateFormatString;
					tokenReader.DateParseHandling = reader.DateParseHandling;
					tokenReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
					tokenReader.FloatParseHandling = reader.FloatParseHandling;
					tokenReader.SupportMultipleContent = reader.SupportMultipleContent;

					// start
					tokenReader.ReadAndAssert();

					reader = tokenReader;
				}

				if (ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, member, containerContract, containerMember,
					existingValue, out var newValue, out id)) return newValue;
			}
			else
			{
				reader.ReadAndAssert();
				if (ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue,
					out var newValue, out id)) return newValue;
			}

			if (HasNoDefinedType(contract)) return CreateJObject(reader);

			MiscellaneousUtils.Assert(resolvedObjectType != null);
			MiscellaneousUtils.Assert(contract != null);

			switch (contract.ContractType)
			{
				case JsonContractType.Object:
				{
					var createdFromNonDefaultCreator = false;
					var objectContract = (JsonObjectContract)contract;
					object targetObject;
					// check that if type name handling is being used that the existing value is compatible with the specified type
					if (existingValue != null && (resolvedObjectType == objectType || resolvedObjectType.IsAssignableFrom(existingValue.GetType())))
						targetObject = existingValue;
					else
						targetObject = CreateNewObject(reader, objectContract, member, containerMember, id, out createdFromNonDefaultCreator);

					// don't populate if read from non-default creator because the object has already been read
					if (createdFromNonDefaultCreator) return targetObject;

					return PopulateObject(targetObject, reader, objectContract, member, id);
				}
				case JsonContractType.Primitive:
				{
					var primitiveContract = (JsonPrimitiveContract)contract;
					// if the content is inside $value then read past it
					if (Serializer.MetadataPropertyHandling != MetadataPropertyHandling.Ignore
						&& reader.TokenType == JsonToken.PropertyName
						&& string.Equals(reader.Value!.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
					{
						reader.ReadAndAssert();

						// the token should not be an object because the $type value could have been included in the object
						// without needing the $value property
						if (reader.TokenType == JsonToken.StartObject)
							throw JsonSerializationException.Create(reader,
								"Unexpected token when deserializing primitive value: " + reader.TokenType);

						var value = CreateValueInternal(reader, resolvedObjectType, primitiveContract, member, null, null, existingValue);

						reader.ReadAndAssert();
						return value;
					}
					break;
				}
				case JsonContractType.Dictionary:
				{
					var dictionaryContract = (JsonDictionaryContract)contract;
					object targetDictionary;

					if (existingValue == null)
					{
						var dictionary = CreateNewDictionary(reader, dictionaryContract, out var createdFromNonDefaultCreator);

						if (createdFromNonDefaultCreator)
						{
							if (id != null)
								throw JsonSerializationException.Create(reader,
									"Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: {0}."
										.FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

							if (contract.OnSerializingCallbacks.Count > 0)
								throw JsonSerializationException.Create(reader,
									"Cannot call OnSerializing on readonly dictionary, or dictionary created from a non-default constructor: {0}."
										.FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

							if (contract.OnErrorCallbacks.Count > 0)
								throw JsonSerializationException.Create(reader,
									"Cannot call OnError on readonly list, or dictionary created from a non-default constructor: {0}.".FormatWith(
										CultureInfo.InvariantCulture, contract.UnderlyingType));

							if (!dictionaryContract.HasParameterizedCreatorInternal)
								throw JsonSerializationException.Create(reader,
									"Cannot deserialize readonly or fixed size dictionary: {0}.".FormatWith(CultureInfo.InvariantCulture,
										contract.UnderlyingType));
						}

						PopulateDictionary(dictionary, reader, dictionaryContract, member, id);

						if (createdFromNonDefaultCreator)
						{
							var creator = (dictionaryContract.OverrideCreator ?? dictionaryContract.ParameterizedCreator)!;

							return creator(dictionary);
						}
						if (dictionary is IWrappedDictionary wrappedDictionary) return wrappedDictionary.UnderlyingDictionary;

						targetDictionary = dictionary;
					}
					else
						targetDictionary =
							PopulateDictionary(
								dictionaryContract.ShouldCreateWrapper || !(existingValue is IDictionary)
									? dictionaryContract.CreateWrapper(existingValue)
									: (IDictionary)existingValue, reader, dictionaryContract, member, id);

					return targetDictionary;
				}
#if HAVE_DYNAMIC
                case JsonContractType.Dynamic:
                    JsonDynamicContract dynamicContract = (JsonDynamicContract)contract;
                    return CreateDynamic(reader, dynamicContract, member, id);
#endif
#if HAVE_BINARY_SERIALIZATION
                case JsonContractType.Serializable:
                    JsonISerializableContract serializableContract = (JsonISerializableContract)contract;
                    return CreateISerializable(reader, serializableContract, member, id);
#endif
			}

			var message =
				@"Cannot deserialize the current JSON object (e.g. {{""name"":""value""}}) into type '{0}' because the type requires a {1} to deserialize correctly."
				+ Environment.NewLine +
				@"To fix this error either change the JSON to a {1} or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object."
				+ Environment.NewLine;
			message = message.FormatWith(CultureInfo.InvariantCulture, resolvedObjectType, GetExpectedDescription(contract));

			throw JsonSerializationException.Create(reader, message);
		}