/**
 * test/Address.ets
 *
 * Manually generated code for testing Visitor pattern V2.0
 */

import { Message, Visitor, Reader } from '../runtime/arkpb'

/**
 * Address message
 */
export class Address extends Message {
  // Type name for reflection
  readonly $typeName: string = 'test.Address'
  static readonly typeName: string = 'test.Address'

  // Fields
  street: string = ''
  city: string = ''
  zipCode: string = ''

  // Constructor
  constructor() {
    super()
  }

  // ⭐ Core: traverse method for Visitor pattern
  traverse(v: Visitor): void {
    if (this.street !== '') {
      v.visitString(this.street, 1)
    }
    if (this.city !== '') {
      v.visitString(this.city, 2)
    }
    if (this.zipCode !== '') {
      v.visitString(this.zipCode, 3)
    }
  }

  // Decode from Reader
  protected decodeFrom(r: Reader, len?: number): void {
    const endPos = len === undefined ? r.len : r.pos + len

    while (r.pos < endPos) {
      const tag = r.uint32()
      const fieldNum = tag >>> 3

      switch (fieldNum) {
        case 1:
          this.street = r.string()
          break
        case 2:
          this.city = r.string()
          break
        case 3:
          this.zipCode = r.string()
          break
        default: {
          // Save unknown fields
          const wireType = tag & 7
          const start = r.pos
          r.skipType(wireType)
          this.unknownFields.append(r.view(start, r.pos))
        }
      }
    }
  }

  // Static factory methods
  static create(init?: Partial<Address>): Address {
    const msg = new Address()
    if (init) {
      if (init.street !== undefined) msg.street = init.street
      if (init.city !== undefined) msg.city = init.city
      if (init.zipCode !== undefined) msg.zipCode = init.zipCode
    }
    return msg
  }

  static build(builder: (msg: Address) => void): Address {
    const msg = new Address()
    builder(msg)
    return msg
  }

  static fromBinary(data: Uint8Array): Address {
    return new Address().fromBinary(data) as Address
  }

  static fromJson(json: Record<string, Object>): Address {
    return new Address().fromJson(json) as Address
  }

  // Validation
  validate(): string | null {
    return null
  }

  // Clear all fields
  clear(): this {
    this.street = ''
    this.city = ''
    this.zipCode = ''
    this.unknownFields.clear()
    return this
  }

  // Check if all fields are default
  isEmpty(): boolean {
    return this.street === '' &&
           this.city === '' &&
           this.zipCode === '' &&
           this.unknownFields.isEmpty()
  }
}