Spesifikasi bahasa

Halaman ini menentukan Vehicle Service Interface Definition Language (VSIDL) menggunakan Extended Backus-Naur Form (EBNF) ISO/IEC 14977 dan protobuf. Halaman ini berfokus pada tata bahasa bebas konteks dan makna elemen bahasa.

Hierarki bahasa

Menurut Meta Object Facility (MOF), compiler VSIDL (VSIDLC) menggunakan bahasa yang ditunjukkan pada Gambar 1:

Bahasa VSIDLC

Gambar 1. Bahasa VSIDLC.

VSIDLC terutama didasarkan pada bahasa buffer protokol (protobuf). Protobuf digunakan untuk menentukan jenis data yang dipertukarkan menggunakan panggilan publish-subscribe dan panggilan prosedur jarak jauh (RPC). Dari sudut pandang teknis, model VSIDL adalah file TextProto, dengan sintaksis VSIDL ditentukan dalam file protobuf (syntax.proto). File protobuf untuk menentukan jenis data dan model VSIDL digunakan untuk menghasilkan kode Rust. Kode yang dihasilkan terutama berisi struct yang mengimplementasikan struktur data untuk pesan yang dipertukarkan dan fungsi Rust yang mengimplementasikan fungsi untuk membuat unit layanan di Rust, tanpa memanggil unit layanan ini secara otomatis. Kode Rust yang dihasilkan ini disertai dengan kode Rust kustom yang menggunakan kode yang dihasilkan untuk membuat instance unit layanan dan mengimplementasikan logika bisnis aplikasi.

Sintaksis abstrak

Gambar 2 menunjukkan jenis pesan inti di VSIDL:

Jenis pesan inti di VSIDL

Gambar 2. Jenis pesan inti di VSIDL.

Entri VSIDL

Bagian ini menjelaskan jenis pesan entri VSIDL.

Tata bahasa EBNF

start VsidlEntry =
  "package" , ":" , String , ";" ,
  { "service_bundle" , ServiceBundle } ,
  { "extension" , ":" , Any } ,
  { "some_ip_mapping" , ":" , SomeIpMapping } ,
  { "vhal_mapping" , ":" , VhalMapping }
;

Definisi proto

// The root message for VSIDL files
message VsidlEntry {
  // Required. Package name for entities mentioned in the file.
  string package = 1;
  // Enables custom extensions beyond the standard VSIDL model.
  repeated google.protobuf.Any extension = 3;

  // SOMEIP mapping rules
  repeated sdv.someip.v1.SomeIpMapping some_ip_mapping = 4;
  // VHAL mapping rules
  repeated VhalMapping vhal_mapping = 5;
  // List of SDV service bundles defined in the file.
  repeated ServiceBundle service_bundle = 6;
}

Contoh penggunaan

package: "com.android.sdv.sample.vsidl"

service_bundle {
  name: "Manager"

  publisher {
    message: "TirePressure"
    topic: "front-left"
    topic: "front-right"
    capacity: 10
  }
}

Penjelasan

Pesan VsidlEntry berfungsi sebagai penampung root untuk file VSIDL (dengan ekstensi .vsidl). Pesan ini merangkum semua definisi dan konfigurasi dalam satu file VSIDL. VsidlEntry adalah elemen tingkat teratas yang mengikat semua hal lainnya.

Tujuan:

  • Mendefinisikan struktur keseluruhan file VSIDL.
  • Menentukan namespace paket untuk semua entity dalam file.
  • Berisi kumpulan definisi paket layanan.
  • Memungkinkan ekstensi kustom ke model VSIDL.
  • Mencakup aturan pemetaan untuk SOME/IP dan VHAL.

Batasan

  • Nama paket (E211): Nama paket tidak boleh melebihi 127 karakter.
  • File yang tidak terkait (E10B): Semua file dalam katalog harus direferensikan dalam grup file Android.bp.

Paket layanan

Bagian ini menjelaskan jenis pesan paket layanan.

Tata bahasa EBNF

ServiceBundle = "{" , { ServiceBundleElement } , "}" ;

ServiceBundleElement =
  "name" , ":" , String |
  "publisher" , Publisher |
  "subscriber" , Subscriber |
  "server" , Server |
  "client" , Client |
  "extension" , ":" , Any |
  "diagnostics_declaration" , DiagnosticsDeclaration |
  "build_cfg" , BuildConfiguration |
  "register_reflection_metadata" , Boolean
;

Definisi proto

// Defines an SDV service
message ServiceBundle {
  // Required. Name of the service bundle (without the package name).
  string name = 1;
  // List of publications the service bundle provides.
  repeated Publisher publisher = 2;
  // List of publications a service bundle subscribes to.
  repeated Subscriber subscriber = 3;
  // RPC services offered by a service bundle.
  repeated Server server = 4;
  // RPC services consumed by a service bundle.
  repeated Client client = 5;
  // Enables custom extensions beyond the standard VSIDL model.
  repeated google.protobuf.Any extension = 7;

  // Diagnostics declarations
  sdv.diagnostics.v1.DiagnosticsDeclaration diagnostics_declaration = 8;

  // Build Configuration
  optional BuildConfiguration build_cfg = 9;

  // Register metadata for service units provided by this service bundle.
  // Setting this to true will increase the memory footprint
  // and network load significantly.
  bool register_reflection_metadata = 10;
}

Contoh penggunaan

service_bundle {
    name: "SeatController"

    publisher {
      message: "SeatHeating"
      topic: "driver-seat"
      capacity: 10
    }
}

Penjelasan

Paket layanan menentukan pengelompokan logis layanan, penayang, pelanggan, server RPC, dan klien RPC terkait. Paket layanan berfungsi sebagai penampung untuk serangkaian fungsi tertentu dan interaksinya.

Batasan

  • Persyaratan nama paket (E209, E20A, E20B, E20C):
    • Paket layanan harus memiliki nama yang diisi.
    • Nama harus diawali dengan karakter awal ID Unicode yang valid (biasanya huruf).
    • Karakter berikutnya dalam nama harus berupa karakter lanjutan ID Unicode yang valid (biasanya huruf atau angka).
    • Nama tidak boleh berupa kata kunci yang dicadangkan di Rust, Java, atau C++.
  • Keunikan paket global (E309): Setiap paket layanan harus memiliki nama yang sepenuhnya memenuhi syarat (berdasarkan paket dan namanya) yang unik.
  • Keunikan internal (E100, E300, E302, E303, E308):
    • Dalam satu paket layanan, setiap layanan RPC dapat ditayangkan oleh paling banyak satu definisi server.
    • Dalam satu paket layanan, setiap jenis publikasi MULTI_PUB dapat dipublikasikan oleh paling banyak satu definisi penerbit.
    • Dalam satu paket layanan, semua nama unit layanan yang ditentukan pengguna (untuk penayang atau server) harus unik.
    • Dalam satu paket layanan, semua nama unit layanan (baik yang ditentukan pengguna maupun yang dibuat secara otomatis) harus unik.
  • Konvensi penamaan target build (E205, E206, E207, E208): Jika nama target build kustom (build_cfg.target_name) diberikan, nama tersebut harus mematuhi format snake case (huruf kecil, angka, dan satu garis bawah, tidak diawali atau diakhiri dengan garis bawah).
  • Bangun keunikan nama target (E301): Nama target build yang ditentukan pengguna tidak boleh bertabrakan dengan nama target yang dibuat secara otomatis untuk paket layanan lainnya.

Penayang

Bagian ini menjelaskan jenis pesan Penayang.

Tata bahasa EBNF

Publisher = "{" , { PublisherElement } , "}" ;

PublisherElement =
  "message" , ":" , String |
  "topic" , ":" , String |
  "capacity" , ":" , Integer |
  "service_unit_name" , ":" , String
;

Definisi proto

// Represents a publisher within a service bundle.
message Publisher {
  // Name of the service unit. Name may only use characters from [a-z0-9\-]+,
  // must start with [a-z], may not end with a hyphen,
  // and may not contain consecutive hyphens.
  string service_unit_name = 3;
  // Required. The type of data being published.
  string message = 4;
  // Required. The number of messages a publication queue can hold.
  // Must be an even number >= 2.
  int64 capacity = 6;
  // Required. Unique identifier for the publication topic.
  // Must be in lowercase dash-case.
  repeated string topic = 7;
}

Contoh penggunaan

publisher {
  message: "SeatHeating"
  topic: "driver-heating"
  capacity: 10
}

Penjelasan

Jenis pesan Publisher menentukan sumber data yang ServiceBundle disediakan. Jenis pesan ini menentukan jenis data yang dipublikasikan serta topik dan kapasitas spesifik data tersebut.

Topik

Setiap instance Publisher memiliki kolom message yang merujuk ke pesan proto yang dipublikasikan. File ini harus menentukan topik (diwakili oleh topic) dan kapasitas (diwakili oleh capacity).

  • Topik: ID unik untuk topik publikasi. Harus mengikuti dash-case huruf kecil (misalnya, my-topic).
  • Kapasitas: Menentukan ukuran antrean, yaitu, berapa banyak pesan yang dapat ditampung antrean sebelum pesan yang belum dibaca dibuang. Harus berupa bilangan genap yang lebih besar dari atau sama dengan 2.

Nama yang ditentukan pengguna

Penayang dapat memiliki nama unit layanan yang ditentukan pengguna yang menggantikan nama unit layanan yang dipilih secara otomatis. Kemampuan ini memungkinkan pemilihan nama yang lebih pendek. Jika penayang menggunakan nama unit layanan yang ditentukan pengguna, penayang tersebut mungkin hanya menggunakan satu instance, sehingga nama unit layanan ditetapkan secara unik ke satu instance.

# VALID: A publisher assigns a user-defined name to a single instance
publisher {
  message: "SeatHeating"
  topic: "seat-heating-status"
  service_unit_name: "heating-is-off"
}

# ERROR: user-defined names are only allowed if there's only a single instance
publisher {
  message: "SeatHeating"
  topic: "seat-heating-status"
  service_unit_name: "heating-status"
}

Batasan

  • Penempatan penayang (E300): Penayang untuk jenis MULTI_PUB yang sama harus ditentukan dalam paket layanan terpisah.
  • Keunikan nama lokal (E302): Dalam satu paket layanan, semua penerbit harus memiliki nama unit layanan yang ditentukan pengguna yang unik.
  • Keunikan nama global (E304): Penerbit dengan jenis publikasi yang sama harus memiliki nama unit layanan yang ditentukan pengguna dan unik secara global di semua paket layanan.
  • Penamaan saluran tunggal (E306): Nama unit layanan yang ditentukan pengguna hanya dapat ditetapkan ke penayang yang menangani tepat satu instance.
  • Batas satu penayang (E307): Pesan protobuf yang ditandai sebagai SINGLE_PUB hanya dapat dipublikasikan oleh satu penayang di seluruh sistem.
  • Keunikan nama unit layanan (E308): Semua nama unit layanan (baik yang dibuat atau ditentukan pengguna) harus unik dalam paket layanannya; nama yang ditentukan pengguna harus digunakan untuk menyelesaikan konflik dengan nama yang dibuat.
  • Persyaratan spesifikasi varian (E501): Saat penayang menggunakan nama yang ditentukan pengguna untuk jenis dengan beberapa varian, penayang harus menentukan varian yang dipublikasikannya secara eksplisit.
  • Keberadaan penayang untuk pelanggan (E504): Setiap pelanggan yang ditentukan memerlukan setidaknya satu penayang yang sesuai untuk jenis dan varian yang ditentukan.
  • Jenis penayang yang valid (E601): Penayang harus mereferensikan jenis yang sesuai dengan pesan protobuf yang ada.
  • Persyaratan anotasi publikasi (E602): Jenis pesan protobuf yang dirujuk oleh penayang harus menyertakan anotasi SdvPublication.
  • Penggunaan varian yang valid (E606): Jika penayang menentukan varian (instance), varian tersebut harus ada dalam instances_enum yang ditentukan untuk jenis publikasi di protobuf.
  • Kondisi spesifikasi varian (E607): Penerbit dapat menentukan varian (instance) eksplisit hanya jika jenis publikasi menentukan instances_enum di protobuf.
  • Penamaan topik (E20D, E20F): Topik harus menggunakan huruf kecil dengan tanda hubung dan tidak boleh lebih dari 127 karakter.
  • Keunikan topik (E314): Topik harus unik secara global di semua penayang.
  • Persyaratan kapasitas (E406, E407): Kapasitas wajib diisi dan harus berupa bilangan genap >= 2.

Subscriber

Bagian ini menjelaskan jenis pesan Subscriber.

Tata bahasa EBNF

Subscriber = "{" , { SubscriberElement } , "}" ;

SubscriberElement =
  "message" , ":" , String |
  "topic" , ":" , String
;

Definisi proto

// Represents a subscriber within a service bundle.
message Subscriber {
  // Required. The type of data being subscribed to.
  string message = 4;
  // Required. Specific topic(s) of the message to subscribe to.
  // Must match the publisher's topic.
  repeated string topic = 6;
}

Contoh penggunaan

subscriber {
  message: "SeatHeating"
  topic: "driver-seat"
}

Penjelasan

Pesan Subscriber menentukan penerima publikasi yang disediakan ServiceBundle. Pesan ini menentukan jenis data yang disubskripsikan dan topik spesifik dari publikasi tersebut. Jika ada beberapa penayang untuk suatu topik, pelanggan akan menerima pesan yang dipublikasikan oleh semua penayang tersebut.

Batasan

  • Keberadaan penayang (E504): Untuk setiap pelanggan yang ditentukan, setidaknya harus ada satu penayang yang sesuai yang memublikasikan jenis dan varian publikasi yang ditentukan.
  • Jenis langganan yang valid (E608): Pelanggan harus mereferensikan jenis yang sesuai dengan pesan protobuf yang ada yang ditentukan dengan anotasi SdvPublication.
  • Langganan varian yang valid (E609): Jika pelanggan menentukan varian (instance), varian tersebut harus berupa nilai valid yang ditentukan dalam instances_enum dari jenis publikasi protobuf yang sesuai.
  • Topik wajib diisi (E408): Topik wajib diisi untuk pelanggan.
  • Deklarasi ulang topik (E311): Topik pelanggan tidak boleh dideklarasikan ulang dalam paket layanan yang sama.

Server RPC

Bagian ini menjelaskan jenis pesan server RPC.

Tata bahasa EBNF

Server = "{" , { ServerElement } , "}" ;

ServerElement =
  "service" , ":" , String |
  "channel" , ":" , String |
  "service_unit_name" , ":" , String
;

Definisi proto

// Represents an RPC server within a service bundle.
message Server {
  // Deprecated. Name of the service unit.
  string service_unit_name = 3 [ deprecated = true ];
  // Required. Name of the RPC service.
  string service = 4;
  // Required. Name of the RPC channel.
  // Must be in lowercase dash-case.
  string channel = 5;
}

Contoh penggunaan

server {
  service: "SetTemperature"
  channel: "temp-setter"
}

Penjelasan

Pesan Server menentukan server RPC yang disediakan oleh ServiceBundle. Pesan ini menentukan layanan yang diterapkan server dan saluran RPC.

Server RPC mengekspos serangkaian metode yang dapat dipanggil klien dari jarak jauh. Kolom service menentukan nama layanan RPC yang diterapkan server. Layanan ini ditentukan dalam file proto dan diimplementasikan dalam kode Rust kustom. Layanan RPC dapat mencakup metode unary, client-streaming, dan server-streaming, seperti yang ditentukan dalam definisi layanan protobuf. Kolom channel menentukan endpoint komunikasi dan wajib diisi (E409).

Batasan

  • Definisi layanan (E603): Server RPC harus menentukan nilai service yang sesuai dengan nilai service RPC protobuf yang ada.
  • Batas server per layanan (E100): Dalam satu paket layanan, service RPC tertentu dapat ditayangkan oleh paling banyak satu definisi server.
  • Penamaan channel (E20E): Channel RPC harus menggunakan huruf kecil dengan tanda hubung.
  • Channel wajib (E409): Channel RPC wajib diisi.
  • Keunikan saluran (E40B): Saluran RPC hanya boleh digunakan oleh satu layanan.

Klien RPC

Bagian ini menjelaskan jenis pesan klien RPC.

Tata bahasa EBNF

Client = "{" , { ClientElement } , "}" ;

ClientElement =
  "service" , ":" , String |
  "channel" , ":" , String
;

Definisi proto

// Represents an RPC client within a service bundle.
message Client {
  // Required. Name of the RPC service.
  string service = 2;
  // Required. Name of the RPC channel.
  // Must match the server's channel and be in lowercase dash-case.
  string channel = 3;
}

Contoh penggunaan

client {
  service: "SetTemperature"
  channel: "temp-setter"
}

Penjelasan

client menentukan klien RPC yang digunakan oleh ServiceBundle. client menentukan layanan yang berinteraksi dengan klien dan saluran untuk terhubung. Klien dapat berinteraksi dengan metode unary, client-streaming, dan server-streaming, bergantung pada definisi layanan.

Batasan

  • Definisi layanan (E60A): Klien RPC harus menentukan service yang sesuai dengan definisi service protobuf yang ada.
  • Sumber layanan unik (E60B): Definisi protobuf service yang dirujuk oleh service klien RPC harus ditentukan secara unik (tidak ditentukan beberapa kali) di semua file protobuf.
  • Channel wajib (E409): Channel RPC wajib diisi.

Build configuration

Bagian ini menjelaskan jenis pesan konfigurasi Build.

Tata bahasa EBNF

BuildConfiguration = "{" , BuildConfigurationElement, "}" ;

BuildConfigurationElement =
  "target_name" , ":" , String |
  "skip_codegen" , ":" , Boolean
;

Definisi proto

// Defines additional information used to configure build settings
message BuildConfiguration {
  /// Build target name
  optional string target_name = 1;
  // Do not generate code for this service bundle
  optional bool skip_codegen = 2;
}

Contoh penggunaan

build_cfg {
  target_name: "my_custom_target_name"
  skip_codegen: false
}

Penjelasan

BuildConfiguration mengonfigurasi parameter non-standar ServiceBundle untuk pembuatan kode. Semua konfigurasi build bersifat opsional.

  • target_name (opsional string): Menentukan nama target build dalam file Android.bp. Gunakan ini untuk menetapkan nama target dengan nama yang lebih pendek daripada nama yang dipilih secara otomatis.
  • skip_codegen (opsional bool): Menunjukkan apakah pembuatan kode harus dilewati untuk paket layanan ini. Jika disetel ke true, tidak ada kode yang dibuat untuk paket layanan tertentu ini. Hal ini dapat berguna untuk paket layanan yang diterapkan secara manual. Secara default, nilai ini ditetapkan ke false.

Batasan

  • Format nama target (E205, E206, E207, E208): Jika nama target build kustom (build_cfg.target_name) diberikan, nama tersebut harus mengikuti format snake case:
    • Nama ini hanya boleh berisi huruf kecil (a hingga z), angka (0 hingga 9), dan garis bawah (_).
    • Tidak boleh berisi garis bawah berurutan (__).
    • Nama tidak boleh diawali dengan garis bawah.
    • Tidak boleh diakhiri dengan garis bawah.
  • Keunikan nama target (E301): build_cfg.target_name yang ditentukan pengguna harus unik di seluruh sistem build dan tidak boleh berkonflik dengan nama target yang dibuat secara otomatis yang berasal dari definisi paket layanan lainnya.