How to Design a Parser for Bit-Encoded Geo-Messages with Multiple Formatting Specifications in Golang?

I’m currently working on a Go library, while being fairly new to the language, that parses and constructs messages containing geo-location and speed data for various entities (e.g., person, vehicle, etc.). Each entity type has its own unique message format with different bit encodings and scaling factors for the data fields. Here is a simplified example of the input data:

{
  "entityID" : "Whale",
  "data" : {
    "lat" : 29.919787,
    "lon" : 48.0193442,
    "speed" : 35.02
  }
}

The specifications outline that each message type (e.g., aircraft, human, vehicle, etc.) and its fields are encoded differently:

  • Each message type is identified by specific codes (HRD, HUI).
  • Fields have specific bit constraints and scaling according to their HRD and HUI.
  • Fields must be in a specific order for each message type.
Message Type HRD HUI Field Bit Length Scaling
Jet 720 18 Speed 8 bits 0-1024
Prop Plane 720 31 Speed 8 bits 0-512
Human 500 22 Speed 5 bits N/A

Example Encoding Definition from the Spec

HRD 720 Speed (Aircraft)
HUI 18  "Jet"            Scaled: 0 - 1024 -> 0 - 127; Larger 128
HUI 31  "Prop Plane"     Scaled: 0 - 512 -> 0 - 127; Larger 128

Based on these specifications, I need to design a parser in Golang. The parser should:

  1. Extract struct tags used by the user to construct a message.
  2. Validate and process these tags according to the specification.
  3. Ensure fields are in the correct order and encoded properly. NOTE: Correct when sent back to user not when sent to parser from user

Initial Design Thoughts

  • Struct Tags Extraction:
    I plan to use struct tags to specify each field’s format, such as MsgFormat:"HRD HUI BITENCODING". Users of my library will use these tags to define how their data should be encoded.

  • State Machine for Validation and Parsing:

    • Establish “states” that represent valid messages (e.g., Jet, Prop Plane, Human).
    • Validate that the combination of tags forms a valid message as per the specs.
    • Ensure fields are in the expected order for each message type.

However, I’m unsure of the best approach to implement this, especially how to dynamically handle the different encodings and validations based on the entity type and field specifications.

Questions

  1. How should I design the state machine for validating and processing the message formats?

    • Specifically, how can I handle dynamically varying field orders and types?
  2. What is the best way to extract and use struct tags for this purpose in Go?

    • How can these tags be validated against the rules defined in the specification?
  3. Are there any Go libraries or patterns that could simplify parsing and encoding these bit-scaled fields?

Current Thoughts

  1. Designing the State Machine:

    • Each state in the FSM could represent a specific entity type (e.g., Jet, Prop Plane, Human).
    • Transitions would depend on detecting starting fields and validation logic.
    • Use a map or switch to transition between states and validate fields.
  2. Struct Tags in Go:

    • Use reflect to extract and interpret struct tags.
    • Validate tags against specifications and apply encoding/decoding logic dynamically.

I hope this structure and breakdown help clarify the requirements and path forward. Any guidance, patterns, or libraries that can aid in parsing, validation, and encoding within Go would be greatly appreciated. If there are better design patterns or practices for handling custom encoding formats and validations dynamically, I would be open to suggestions.

Thanks in advance!