private IProperty GetProperty(PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
        {
            var property = _visitor.Visit(propertyInfo, attribute);

            if (property != null)
            {
                return(property);
            }

            if (propertyInfo.GetMethod.IsStatic)
            {
                return(null);
            }

            property = attribute ?? InferProperty(propertyInfo);

            if (property is IObjectProperty objectProperty)
            {
                var type      = GetUnderlyingType(propertyInfo.PropertyType);
                var seenTypes = new ConcurrentDictionary <Type, int>(_seenTypes);
                seenTypes.AddOrUpdate(type, 0, (t, i) => ++ i);
                var walker = new PropertyWalker(type, _visitor, _maxRecursion, seenTypes);
                objectProperty.Properties = walker.GetProperties(seenTypes, _maxRecursion);
            }

            _visitor.Visit(property, propertyInfo, attribute);

            return(property);
        }
        public IProperties GetProperties(ConcurrentDictionary <Type, int> seenTypes = null, int maxRecursion = 0)
        {
            var properties = new Properties();

            if (seenTypes != null && seenTypes.TryGetValue(_type, out var seen) && seen > maxRecursion)
            {
                return(properties);
            }

            foreach (var propertyInfo in _type.GetAllProperties())
            {
                var attribute = OpenSearchPropertyAttributeBase.From(propertyInfo);
                if (attribute != null && attribute.Ignore)
                {
                    continue;
                }
                if (_visitor.SkipProperty(propertyInfo, attribute))
                {
                    continue;
                }

                var property = GetProperty(propertyInfo, attribute);
                if (property is IPropertyWithClrOrigin withCLrOrigin)
                {
                    withCLrOrigin.ClrOrigin = propertyInfo;
                }
                properties.Add(propertyInfo, property);
            }

            return(properties);
        }
            private JsonProperty GetMapping(MemberInfo member)
            {
                // TODO: Skip calling this method for OSC and OpenSearch.Net types, at the type level
                if (!_settings.PropertyMappings.TryGetValue(member, out var propertyMapping))
                {
                    propertyMapping = OpenSearchPropertyAttributeBase.From(member);
                }

                var serializerMapping = _settings.PropertyMappingProvider?.CreatePropertyMapping(member);
                var nameOverride      = propertyMapping?.Name ?? serializerMapping?.Name;
                var property          = new JsonProperty(nameOverride);

                var overrideIgnore = propertyMapping?.Ignore ?? serializerMapping?.Ignore;

                if (overrideIgnore.HasValue)
                {
                    property.Ignore = overrideIgnore.Value;
                }

                if (propertyMapping != null || serializerMapping != null)
                {
                    property.AllowPrivate = true;
                }

                if (member.GetCustomAttribute <StringEnumAttribute>() != null)
                {
                    CreateEnumFormatterForProperty(member, property);
                }
                else if (member.GetCustomAttribute <StringTimeSpanAttribute>() != null)
                {
                    switch (member)
                    {
                    case PropertyInfo propertyInfo:
                        property.JsonFormatter =
                            BuiltinResolver.BuiltinResolverGetFormatterHelper.GetFormatter(propertyInfo.PropertyType);
                        break;

                    case FieldInfo fieldInfo:
                        property.JsonFormatter =
                            BuiltinResolver.BuiltinResolverGetFormatterHelper.GetFormatter(fieldInfo.FieldType);
                        break;
                    }
                }
                else if (member.GetCustomAttribute <EpochDateTimeAttribute>() != null)
                {
                    property.JsonFormatter = EpochDateTimeFormatter.Instance;
                }

                return(property);
            }
 public void Visit(IIpRangeProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public void Visit(IPercolatorProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public virtual void Visit(ITokenCountProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public virtual void Visit(IMurmur3HashProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public virtual void Visit(ICompletionProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public virtual void Visit(IShapeProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public virtual bool SkipProperty(PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute) => false;
        public void Visit(IProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
        {
            switch (type)
            {
            case INestedProperty nestedType:
                Visit(nestedType, propertyInfo, attribute);
                break;

            case IObjectProperty objectType:
                Visit(objectType, propertyInfo, attribute);
                break;

            case IBinaryProperty binaryType:
                Visit(binaryType, propertyInfo, attribute);
                break;

            case IBooleanProperty booleanType:
                Visit(booleanType, propertyInfo, attribute);
                break;

            case IDateProperty dateType:
                Visit(dateType, propertyInfo, attribute);
                break;

            case IDateNanosProperty dateNanosType:
                Visit(dateNanosType, propertyInfo, attribute);
                break;

            case INumberProperty numberType:
                Visit(numberType, propertyInfo, attribute);
                break;

            case ITextProperty textType:
                Visit(textType, propertyInfo, attribute);
                break;

            case IKeywordProperty keywordType:
                Visit(keywordType, propertyInfo, attribute);
                break;

            case IGeoShapeProperty geoShapeType:
                Visit(geoShapeType, propertyInfo, attribute);
                break;

            case IShapeProperty shapeType:
                Visit(shapeType, propertyInfo, attribute);
                break;

            case IGeoPointProperty geoPointType:
                Visit(geoPointType, propertyInfo, attribute);
                break;

            case ICompletionProperty completionType:
                Visit(completionType, propertyInfo, attribute);
                break;

            case IIpProperty ipType:
                Visit(ipType, propertyInfo, attribute);
                break;

            case IMurmur3HashProperty murmurType:
                Visit(murmurType, propertyInfo, attribute);
                break;

            case ITokenCountProperty tokenCountType:
                Visit(tokenCountType, propertyInfo, attribute);
                break;

            case IPercolatorProperty percolatorType:
                Visit(percolatorType, propertyInfo, attribute);
                break;

            case IJoinProperty joinType:
                Visit(joinType, propertyInfo, attribute);
                break;

            case IIntegerRangeProperty integerRangeType:
                Visit(integerRangeType, propertyInfo, attribute);
                break;

            case ILongRangeProperty longRangeType:
                Visit(longRangeType, propertyInfo, attribute);
                break;

            case IDoubleRangeProperty doubleRangeType:
                Visit(doubleRangeType, propertyInfo, attribute);
                break;

            case IFloatRangeProperty floatRangeType:
                Visit(floatRangeType, propertyInfo, attribute);
                break;

            case IDateRangeProperty dateRangeType:
                Visit(dateRangeType, propertyInfo, attribute);
                break;

            case IIpRangeProperty ipRangeType:
                Visit(ipRangeType, propertyInfo, attribute);
                break;

            case IRankFeatureProperty rankFeature:
                Visit(rankFeature, propertyInfo, attribute);
                break;

            case IRankFeaturesProperty rankFeatures:
                Visit(rankFeatures, propertyInfo, attribute);
                break;

            case IHistogramProperty histogram:
                Visit(histogram, propertyInfo, attribute);
                break;

            case IPointProperty point:
                Visit(point, propertyInfo, attribute);
                break;

            case ISearchAsYouTypeProperty searchAsYouType:
                Visit(searchAsYouType, propertyInfo, attribute);
                break;

            case IWildcardProperty wildcard:
                Visit(wildcard, propertyInfo, attribute);
                break;

            case IFieldAliasProperty fieldAlias:
                Visit(fieldAlias, propertyInfo, attribute);
                break;

            case IVersionProperty version:
                Visit(version, propertyInfo, attribute);
                break;
            }
        }
 public virtual IProperty Visit(PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute) => null;
 public virtual void Visit(IFieldAliasProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }
 public virtual void Visit(IRankFeaturesProperty type, PropertyInfo propertyInfo, OpenSearchPropertyAttributeBase attribute)
 {
 }