คุณสามารถกำหนดค่าหลายประเภทให้กับฟิลด์เดียวในข้อความ Protobuf ซ้ำได้หรือไม่

ฉันกำลังพยายามทำวิศวกรรมย้อนกลับไคลเอนต์ที่อัปโหลดไฟล์เสียงไปยังเซิร์ฟเวอร์ จากนั้นอัปโหลดข้อมูลเมตาของไฟล์ในคำขอแยกต่างหากในภายหลัง ข้อมูลเมตาถูกทำให้เป็นอนุกรมใน Protobuf และใช้โครงสร้างที่ค่อนข้างเรียบง่ายและอ่านง่าย ต่อไปนี้จะมีลักษณะดังนี้หลังจาก protoc --decode_raw:

1 {
  1: "title"
  2: "This is the audio title"
}
1 {
  1: "tags"
  2 {
  }
}
1 {
  1: "loc"
  2: "This is the location"
}
1 {
  1: "transcription"
  2: "A transcript"
}
1 {
  1: "mapping"
  2 {
    1 {
      1: 6
      2 {
        3: 840
      }
    }
    2: 6
  }
}

ดูเหมือนว่าจะเป็นเพียงข้อความซ้ำที่ช่อง 1 ที่เก็บคู่คีย์-ค่าในแต่ละครั้ง แต่บางครั้งค่าอาจเป็นสตริง และบางครั้งก็เป็นข้อความที่ซับซ้อนมากขึ้น พวกเขาจะกำหนดทั้งสตริงและข้อความให้กับฟิลด์ 2 ได้อย่างไรหาก Protobuf ให้คุณใช้ค่าเพียงประเภทเดียวต่อฟิลด์ ถ้าฉันจะสร้างคำขอของตัวเอง ฉันต้องการสิ่งนี้:

message KeyValuePair {
    string key = 1;
    oneof value {
        string str_value = 2;
        MessageValue msg_value = 2;
    }
}

แต่นั่นไม่ได้ผล เพราะ Field number 2 has already been used in "package.name" by field "str_value" มีความคิดอะไรบ้าง? ฉันจะใช้ Python เพื่อสร้างและส่งข้อมูลคำขอ


person twentythousand    schedule 21.03.2021    source แหล่งที่มา


คำตอบ (1)


มีวิธีที่เป็นทางการในการบรรลุเป้าหมายนี้: google.protobuf.Any

หากสคีมา protobuf กำหนดสิ่งใดๆ ที่ระดับบนสุด เช่น:

message Root {
  repeated google.protobuf.Any value = 1;
}

message Title {
  string title= 2;
}

message Tags {
  string name = 1;
  repeated string tags = 2;
}

จากนั้นข้อความประเภทใดๆ ก็ตามที่ Protobuf กำหนดสามารถถูกทำให้เป็นอนุกรมในรายการได้

อย่างไรก็ตาม ฉัน คิด นั่นคือสิ่งที่โค้ดที่มีอยู่กำลังทำอยู่:

  • โดยปกติแล้วเอาต์พุตดิบสำหรับ Any จะรวม URL ประเภท type.googleapis.com ด้วย
  • เมื่อใช้ Any ฟิลด์ title / loc จะถูกห่อหุ้มไว้ในออบเจ็กต์ที่ซ้อนกัน ไม่ใช่สตริงในระดับเดียวกัน

E.g.:

1 {
  1: "type.googleapis.com/Title"
  2 {
    1: "the title"
  }
}
person Peter Wishart    schedule 22.03.2021